karate: JS / Multi threaded access error when using karate.callSingle()

I mentioned this issue here: https://github.com/intuit/karate/issues/1373#issuecomment-788636073

Thought it might be fixed in #1480 in 1.0 but it appears not having tried the release version this morning.

Here is a minimal repro repo: https://github.com/JoshSchreuder/karate-repro

0.9.6 java "-Dkarate.config.dir=C:\Temp\karaterepro" -jar "C:\temp\karate0.9.6.jar" "C:\Temp\karaterepro\demo\api" is working with no issues

1.0.0 java "-Dkarate.config.dir=C:\Temp\karaterepro" -jar "C:\temp\karate1.0.jar" "C:\Temp\karaterepro\demo\api" fails with

org.graalvm.polyglot.PolyglotException: java.io.FileNotFoundException: C:\Temp\karaterepro\demo\api\C:\Temp\karaterepro\features\auth\auth.feature (The filename, directory name, or volume label syntax is incorrect)
- com.intuit.karate.resource.FileResource.getStream(FileResource.java:98)
- com.intuit.karate.core.FeatureParser.parse(FeatureParser.java:73)
- com.intuit.karate.core.Feature.read(Feature.java:67)
- com.intuit.karate.core.ScenarioFileReader.readFile(ScenarioFileReader.java:64)
- com.intuit.karate.core.ScenarioBridge.read(ScenarioBridge.java:625)
- com.intuit.karate.core.ScenarioBridge.callSingle(ScenarioBridge.java:209)
- com.intuit.karate.core.ScenarioBridge.callSingle(ScenarioBridge.java:155)

It looks like it’s appending the test directory to the start of the callSingle call? Couldn’t find anything in the breaking changes about this, so not sure if it’s intentional or a bug.

I’m on Windows 10 x64 21H1. Java:

openjdk 11.0.10 2021-01-19
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.10+9)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.24.0, JRE 11 Windows 10 amd64-64-Bit Compressed References 20210120_899 (JIT enabled, AOT enabled)
OpenJ9   - 345e1b09e
OMR      - 741e94ea8
JCL      - 0a86953833 based on jdk-11.0.10+9)

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 60 (49 by maintainers)

Commits related to this issue

Most upvoted comments

thank you @aleruz ! I think we are ready to release

Oh and finally… getting an exception when running in multi threaded mode with my callSingle in karate.config.js (I think that’s why).

org.graalvm.polyglot.PolyglotException: Multi threaded access requested by thread Thread[pool-1-thread-1,5,main] but is not allowed for language(s) js.
- com.oracle.truffle.polyglot.PolyglotEngineException.illegalState(PolyglotEngineException.java:132)
- com.oracle.truffle.polyglot.PolyglotContextImpl.throwDeniedThreadAccess(PolyglotContextImpl.java:727)
- com.oracle.truffle.polyglot.PolyglotContextImpl.checkAllThreadAccesses(PolyglotContextImpl.java:627)
- com.oracle.truffle.polyglot.PolyglotContextImpl.enterThreadChanged(PolyglotContextImpl.java:526)
- com.oracle.truffle.polyglot.PolyglotEngineImpl.enter(PolyglotEngineImpl.java:1857)
- com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:104)
- com.oracle.truffle.polyglot.PolyglotMap.entrySet(PolyglotMap.java:119)

I’ll try and repro this minimally also.

1.0.1 released

@ptrthomas 🎉 seems this time is THE time 🎉 In my case no more issue! 👏🏻 Sad I could not reproduce it in an own separate example.

Tested the scenarios I had with that additional fix and works great. Thanks @ptrthomas , will check in a few things on top of that test for completeness that I tried in my local. @aleruz keep us posted on your results.

okay one more time, my last commit is again a simple one but with one critical fix for “magic variables” that I really hope is the end of it

would be great if everyone here can try this version

@aleruz question on your scenario, you said your feature called by callSingle() does a call twice to the same feature with different parameters.

Few questions on that - are those parameters reused within that call and how does that loop work? Any chance you can drop a screenshot here of that piece only and take out any private names / paths you might have?

one more question for all, we now think that one of the causes could be the use of configure headers = fun or karate.configure('headers', fun) and where fun is a JS function

can y’all have a look whether that was involved. the other suspects are:

  • karate.callSingle() where you have passed some value as the second argument
  • use of Background
  • use of callonce
  • callonce or karate.callSingle() threw an Exception

I started from the blueprint, as suggested in https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue. Using the ParallelTest.java, trying to create a main feature which calls a sub-feature which calls another sub-feature. I also added some “Thread.sleep” to simulate a slow API (that is actually my real case). In parallel, trying to understand what in my current tests can be a reason for the failure.

My current status is in this repo: https://github.com/aleruz/karate-call-single-bug

@ptrthomas I am on Mac as well. I am trying to debug right now, and found two things which seems to change the result of my test making it pass. But I need a bit more time to test it. At the moment, my suspicion is on two parallel runners which I created with different tags but which may be interfering in some tests (that was an experiment I did and that did not create issue with 0.9.6). Removing one of the two, seems to let the test pass now. But, I want to be sure. Will keep you posted here.

reopening and making sure @aleruz is part of the conversation 😃

@JoshSchreuder & @joelpramos - we have another report of the callSingle() issue here: https://stackoverflow.com/q/66651979/143475

I’ve asked the OP to comment in this thread. and meanwhile I tried my best to replicate the situation of a callSingle + feature + HTTP call in our “parallel” test that already mixes a callonce, here is the commit: https://github.com/intuit/karate/commit/89f68168a43343975ce5d986811ba1d814d39b1d

and it still seems to work fine. but hopefully y’all will be able to see what’s that extra bit in your tests that causing this problem.

ugh yes, that’s an edge case with the match parser which I hadn’t considered.

just for completeness, this should work (long story): * match (response.data.length) == 50 will see if this can be improved

and the exception is very bad news 😐 cc @joelpramos

if your callSingle is setting up functions, try removing those and stick to pure data. else well. we need to dig

Oh I worked out the length thing, needed to change to And assert response.data.length == 50

cc @kirksl to be aware of VS Code extension usage

actually we prefer karate.sizeOf(array) since we don’t want to trust the JS engine to do array length calcs

@ptrthomas yeah my apologies, I didn’t have anything setup to build a new JAR off the source at the time.

Anyway, switching to file: seems to work quite well I think, I will try it out with my main project. If overriding karate.config.dir is not supported and for internal use only I’m fine if you want to close this if the workaround works just as well.