karate: karate.callSingle/callonce crashes where karate.call succeeds
Hi, In our karate-config, I use a lot of Java.type(‘XXX’) to call custom Java code. As it is somehow “heavy” (authentication against a provider), I want this to get called only once for all my tests, and not before each of my 400+ tests (thus the callSingle in karate-config, instead of having all the code in karate-config).
In karate 0.9.6, the following worked :
karate-config.js :
function configure_karate() {
var load_config=karate.callSingle('classpath:load-config.js')
return load_config
}
load-config.js :
function load_config() {
var config = {}
config.spec = Java.type('package.CustomJavaClass').spec // spec if a static function of CustomJavaClass
return config
}
while it crashes using the latest Karate releases (tried with both 1.0.1 and 1.1.0.RC2) with following stacktrace :
org.graalvm.polyglot.PolyglotException
- com.intuit.karate.graal.JsFunction.<init>(JsFunction.java:39)
- com.intuit.karate.core.ScenarioEngine.recurseAndDetachAndDeepClone(ScenarioEngine.java:1208)
- com.intuit.karate.core.ScenarioEngine.lambda$recurseAndDetachAndDeepClone$15(ScenarioEngine.java:1225)
- java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:723)
- com.intuit.karate.core.ScenarioEngine.recurseAndDetachAndDeepClone(ScenarioEngine.java:1225)
- com.intuit.karate.core.ScenarioEngine.recurseAndDetachAndDeepClone(ScenarioEngine.java:1201)
- com.intuit.karate.core.ScenarioBridge.callSingle(ScenarioBridge.java:235)
I know there have been huge changes from 0.9.6 to 1+, but what bugs me is that using karate.call('classpath:load-config.js') works in karate 1+ versions.
So, the behavior is different between karate.call and karate.callSingle.
After some digging into karate inner sources, starting from ScenarioBridge, and some testing, the problem is due to the fact
spec is a function, and karate.call and karate.callSingle handle functions differently.
To my understanding, those functions should have the same behavior, with the latter caching the result for subsequent calls. Am I wrong ? I set up a minimal project in this repo for easier reproduction. https://github.com/zgael/karateconfig
Feel free to ask for clarifications if needed !
Thanks!
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 15 (13 by maintainers)
Commits related to this issue
- attempt to resolve #1633 but nope related to #1558 there are code changes in this commit - got rid of the synchronize and a better understanding of graal for e.g. Value.isMetaObject() returns false fo... — committed to karatelabs/karate by ptrthomas 3 years ago
- clean up websocket listen routine and try to prevent occasional ci failure mentioned here: https://github.com/intuit/karate/issues/1633#issuecomment-859651302 — committed to karatelabs/karate by ptrthomas 3 years ago
- comment out java method ref from js #1633 — committed to karatelabs/karate by ptrthomas 3 years ago
- attempt to make even java method refs work in callSingle #1558 #1633 — committed to karatelabs/karate by ptrthomas 3 years ago
- this is too flaky for comfort, commenting out #1633 — committed to karatelabs/karate by ptrthomas 3 years ago
- reasonable solution for #1633 #1558 and java function references which is to pass java functions around as Function instances not JS snippets which means they become graal host objects - which do not ... — committed to karatelabs/karate by ptrthomas 3 years ago
attention all cc @zgael @joelpramos @aleruz
I figured out a way where you can use Java functions safely even within a
callonceorkarate.callSingle(), it is not completely straightforward, but I think a very reasonable compromise. it makes me relieved because I am confident Karate can be made to work for advanced JMS and Kafka kinds of use-cases in a stable way, where earlier I thought graal would very badly get in the waysee doc screenshot below, and direct link is here: https://github.com/intuit/karate/tree/develop#java-function-references
sure. one of the points above is that you shouldn’t put Java methods and such in a
callSingle()do it as many times as you want in a normalcall.callSingle()is designed for caching data, not java code.for readability, you can wrap it into a feature following the instructions here: https://github.com/intuit/karate#multiple-functions-in-one-file
no not too late, as of now I consider we are done with the fixes here. FWIW here is what we have in the documentation in the next version - screenshot below: https://github.com/intuit/karate/tree/develop#karatecallsingle