How can you use WorkerAction with the TestListener...
# community-support
p
How can you use WorkerAction with the TestListener? I don't want to use a main function and pass all the parameters untyped
v
Mind elaborating what you are talking about? At least me I have no idea what you mean.
p
The ExecOperations will be run synchronously and it blocks the current listener, like when called in
afterSuite
. Will WorkerExecutor also block the listener?
v
AH, ok, did you just try it? 🙂 Unfortunately it is not really documented what you can legally inject where.
p
Nope, not yet, because testing it is little bit painful, but yeah will do it
Btw. how do you instantiate the listener? The method you mentioned takes a concrete instance.
p
objects.newInstance(UploadXRayResults::class)
v
And why is it hard to test?
Copy code
abstract class MyTestListener : TestListener {
    @get:Inject
    abstract val execOperations: ExecOperations
    @get:Inject
    abstract val workerExecutor: WorkerExecutor
    init {
        println(execOperations)
        println(workerExecutor)
    }
    override fun beforeSuite(suite: TestDescriptor?) = Unit
    override fun afterSuite(suite: TestDescriptor?, result: TestResult?) = Unit
    override fun beforeTest(testDescriptor: TestDescriptor?) = Unit
    override fun afterTest(testDescriptor: TestDescriptor?, result: TestResult?) = Unit
}
tasks.test {
    addTestListener(objects.newInstance<MyTestListener>())
}
et voilá, works 🙂
Copy code
org.gradle.process.internal.DefaultExecOperations_Decorated@1dd1c241
org.gradle.workers.internal.DefaultWorkerExecutor_Decorated@4613c0c6
p
Oh... you are right, I could test it inline, fail...
I was about to rewrite my whole implementation...
Thank you!
👌 1
Hm, now I get this error:
An attempt was made to submit work from a thread not managed by Gradle.  Work may only be submitted from a Gradle-managed thread.
v
Hm, maybe a bug? Sounds like the thread should be managed by Gradle. Or it is not supported, no idea. Maybe check on which thread this actually is called?
p
Hm, it does work with kotlin.lazy... Still a bug:
Copy code
abstract class MyTestListener : TestListener {
    @get:Inject
    abstract val workerExecutor: WorkerExecutor

    private val s by lazy {
        val s = workerExecutor.noIsolation()
        s.submit(FooWork::class) {
        }
        s.await()
        42
    }

    override fun beforeSuite(suite: TestDescriptor) = Unit
    override fun afterSuite(suite: TestDescriptor, result: TestResult) {
        println(s)
    }

    override fun beforeTest(testDescriptor: TestDescriptor) = Unit
    override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) = Unit
}

abstract class FooWork : WorkAction<WorkParameters.None> {
    override fun execute() {
        println("Running Foo work")
    }
}

tasks.test {
    addTestListener(objects.newInstance<MyTestListener>())
}
Looks like the JUnit framework calls the
afterSuite
function with its own thread