https://kotlinlang.org logo
#kotest
Title
# kotest
w

wasyl

05/16/2021, 12:19 PM
Another one 😄 https://github.com/kotest/kotest/commit/a0ea126434401074dc8d1839fb986c23a74780c1 this commit didn’t really change anything because I was running tests with Gradle, and this discovery path is not even hit — Gradle (Junit?) passes all requested tests classes already, Kotest just filters them to keep Spec instances. The 4GB of memory that ClassGraph takes is triggered by
detectConfig()
. Disabling jar scanning for it is not reasonable, because jars may provide listeners. So while config discovery is pretty useful, would you consider some other mechanism for that? I know that scanning can be disabled, but then modules wouldn’t be able to provide useful listeners (I think I even requested discovery at one point, to avoid having to declare a merged project config in each module). One thing that comes to mind is allowing everything that can be AutoScanned now to be provided via ServiceLoaders. Locally I just hardcoded our listeners and got that peak memory down from 4GB to 1GB. Bottom line: ClassGraph has significant memory impact, at least with larger projects. It’d be nice to have a way to completely bypass it. Btw in addition to memory usage, it also spawns several threads (in my case 18!) that it never releases.
Out of curiosity, when are tests discovered via classgraph? When running Kotest directly on jars from command line somehow, or from junit maybe?
s

sam

05/16/2021, 3:00 PM
When classes aren't specified
So probably never?
😄 1
As gradle specifies them and so does the intellij plugin
w

wasyl

05/16/2021, 3:15 PM
Makes sense, I wonder if someone managed to run Kotest without specifying test classes 😄
s

sam

05/16/2021, 3:16 PM
Lol i think the package run in intellij does that
w

wasyl

05/16/2021, 3:19 PM
I’ll be honest I almost never use that 😄 And I admit I’m mostly looking for optimisations in my workflow, which is running entire module tests via Gradle and maybe running single test from IDE later on
I can draft service loader support later on but I’m not very familiar with Kotest tests suite so that might take a while
s

sam

05/16/2021, 3:20 PM
If we limit scanning to classes only it should work
Although the ones shipped with kotest itself are in jars
Service loader is JVM only too so must be opt in
😕 1
w

wasyl

05/16/2021, 3:21 PM
Right, I forgot 😕
s

sam

05/16/2021, 3:21 PM
You don't need autoscan. You can already disable it
w

wasyl

05/16/2021, 3:21 PM
If we limit scanning to classes only it should work
We also have listeners in other modules, and the case for scanning was to allow modules to contribute listeners just by adding a dependency on them
s

sam

05/16/2021, 3:22 PM
Right
w

wasyl

05/16/2021, 3:22 PM
And that’s why we can disable autoscan, but will have to register those contributed listeners in each module specifically. Not terrible but still some overhead
s

sam

05/16/2021, 3:22 PM
Service loader as an alternative is absolutely fine
w

wasyl

05/16/2021, 3:23 PM
I’ll see if I can figure out something multiplatform-friendly, or maybe Kotlin folks are working on a Kotlin-specific alternative
s

sam

05/16/2021, 3:23 PM
The include packages setting might be sufficient
w

wasyl

05/16/2021, 3:24 PM
I think I tried that and didn’t see much improvement, but I’m not sure now. I’ll check again, you mean to add option to specify
acceptPackages
argument?
Actually, another option would be to specify listeners/extensions classes names that may be on the classpath and use them if they are. That’s pretty inflexible but not terrible either (I’m just looking for ways to sidestep ClassGraph completely)
s

sam

05/16/2021, 3:26 PM
If we use service loader then the JDK still has to open up the jars to look for the descriptor files
Assuming that classgraph is efficient, using the acceptPackages argument would skip a ton of class scanning
I can add that option in like 5 minutes if you want to try a build
w

wasyl

05/16/2021, 3:28 PM
I already figured out how to prototype things quickly locally 🙂 Got a local build and publish whatever I change
s

sam

05/16/2021, 3:28 PM
Ok, and it made no diff ?
w

wasyl

05/16/2021, 3:29 PM
I don’t recall, I’ll check it later today, gotta afk for a while
👍🏻 1
s

sam

05/16/2021, 3:29 PM
I'll push a change to close down the classgraph threads at least
w

wasyl

05/16/2021, 3:29 PM
Also I still want to hunt down that 1GB of memory early on, I have a feeling is a bit more than needed, but haven’t found it yet. But yeah I’ll try some variants and let you know the results 🙂
👍🏻 1
s

sam

05/16/2021, 3:30 PM
and when you're back later - classgraph is used in two places, so make sure you put acceptPackages in both
w

wasyl

05/16/2021, 7:33 PM
But one is not hit when running from Gradle, right? Anyway I specified packages in both places, with no difference in memory usage, still 4GB
I’ll push a change to close down the classgraph threads at least
That’s my bad, the threads are closed right after scanning, the missing
scanResult.close()
in
detektConfig.kt
is just to clean up some files. I looked at the profiler wrong
s

sam

05/16/2021, 8:05 PM
ok I did update the code to call close in detect anyway
4 Views