Eel tests + Python: API to skip remote eels on certain OSes, use it for PyCharm test.

See `TestApplicationWithEel` for the explanation of `osesMayNotHaveRemoteEels` option.

See `RunExecutableTest` for usage.

GitOrigin-RevId: b7546d831328087993a6fc8e53ccf39dcd758bc5
This commit is contained in:
Ilya.Kazakevich
2025-05-06 10:03:28 +00:00
committed by intellij-monorepo-bot
parent 908ad3f351
commit 2378865181
4 changed files with 25 additions and 13 deletions
@@ -4,6 +4,7 @@ package com.intellij.platform.testFramework.junit5.eel.params.api
import com.intellij.platform.testFramework.junit5.eel.params.impl.junit5.EelInterceptor
import com.intellij.testFramework.junit5.TestApplication
import org.jetbrains.annotations.TestOnly
import org.junit.jupiter.api.condition.OS
import org.junit.jupiter.api.extension.ExtendWith
/**
@@ -27,8 +28,16 @@ import org.junit.jupiter.api.extension.ExtendWith
* ```
* Run a test, and failure will report an option name.
*
* You either need to have providers (i.e. `intellij.platform.ijent.testFramework` in a classpath),
* or disable [atLeastOneRemoteEelRequired]
* System tries to run your test against at least one remote (ijent-based) eel.
* You need to have providers (i.e. `intellij.platform.ijent.testFramework` in a classpath) to do that.
*
* If your particular test doesn't need remote eels for a certain OS, use [osesMayNotHaveRemoteEels].
*
* The following test will fail if no remote Eel available on any OS but Windows:
* ```kotlin
* @TestApplicationWithEel(osesMayNotHaveRemoteEels=[OS.WINDOWS])
* ```
* Do not use this option unless you are absolutely sure.
*/
@TestOnly
@Target(AnnotationTarget.CLASS)
@@ -36,4 +45,4 @@ import org.junit.jupiter.api.extension.ExtendWith
EelInterceptor::class,
)
@TestApplication
annotation class TestApplicationWithEel(val atLeastOneRemoteEelRequired: Boolean = true)
annotation class TestApplicationWithEel(vararg val osesMayNotHaveRemoteEels: OS)
@@ -16,6 +16,7 @@ import com.intellij.testFramework.junit5.fixture.EelForFixturesProvider
import com.intellij.testFramework.junit5.fixture.EelForFixturesProvider.Companion.makeFixturesEelAware
import kotlinx.coroutines.*
import org.jetbrains.annotations.TestOnly
import org.junit.jupiter.api.condition.OS
import org.junit.jupiter.api.extension.*
import org.junit.platform.commons.util.AnnotationUtils
import org.opentest4j.TestAbortedException
@@ -31,7 +32,7 @@ internal class EelInterceptor : InvocationInterceptor, BeforeAllCallback, Before
val ExtensionContext.atLeastOneRemoteEelRequired: Boolean
get() =
AnnotationUtils.findAnnotation(testClass.get(), TestApplicationWithEel::class.java).get().atLeastOneRemoteEelRequired
OS.current() !in AnnotationUtils.findAnnotation(testClass.get(), TestApplicationWithEel::class.java).get().osesMayNotHaveRemoteEels
val ExtensionContext.store: ExtensionContext.Store get() = getStore(ExtensionContext.Namespace.GLOBAL)
private val ReflectiveInvocationContext<Method>.eelHolderArgs: List<EelHolder>
@@ -53,17 +54,17 @@ internal class EelInterceptor : InvocationInterceptor, BeforeAllCallback, Before
}
override fun beforeAll(context: ExtensionContext) {
// -Djava.nio.file.spi.DefaultFileSystemProvider=com.intellij.platform.core.nio.fs.MultiRoutingFileSystemProvider
val name = MultiRoutingFileSystemProvider::class.qualifiedName!!
assert(System.getProperty(PROVIDER_PROP_NAME) == name) {
"Please add `-D$PROVIDER_PROP_NAME=$name` as VMOption as eel needs custom nio provider"
}
if (context.atLeastOneRemoteEelRequired) {
// -Djava.nio.file.spi.DefaultFileSystemProvider=com.intellij.platform.core.nio.fs.MultiRoutingFileSystemProvider
val name = MultiRoutingFileSystemProvider::class.qualifiedName!!
assert(System.getProperty(PROVIDER_PROP_NAME) == name) {
"Please add `-D$PROVIDER_PROP_NAME=$name` as VMOption as eel needs custom nio provider"
}
assert(getIjentTestProviders().isNotEmpty()) {
"""
No remote (ijent-based) eel implementation was found on class-path.
You have 2 options:
1. Disable ${TestApplicationWithEel::atLeastOneRemoteEelRequired} and stick with the local eel only (not recommended).
1. Add your OS to ${TestApplicationWithEel::osesMayNotHaveRemoteEels} and stick with the local eel only (not recommended).
2. Make sure at least one ${EelIjentTestProvider::class} exists on the class-path.
""".trimIndent()
}
@@ -96,7 +97,7 @@ internal class EelInterceptor : InvocationInterceptor, BeforeAllCallback, Before
error("""
Although some remote (ijent) eel implementations were found on a class-path, all of them were skipped.
That means, you've tested the local eel implementation only!
If that was your plan, set ${TestApplicationWithEel::atLeastOneRemoteEelRequired} and stick with the local eel only (not recommended).
If that was your plan, configure ${TestApplicationWithEel::osesMayNotHaveRemoteEels} and stick with the local eel only (not recommended).
But much better to do the following: $advice
Testing something against local eel only is not recommended.
""".trimIndent())
@@ -4,13 +4,14 @@ package com.intellij.platform.testFramework.junit5.eel.showcase
import com.intellij.platform.testFramework.junit5.eel.params.api.EelHolder
import com.intellij.platform.testFramework.junit5.eel.params.api.EelSource
import com.intellij.platform.testFramework.junit5.eel.params.api.TestApplicationWithEel
import org.junit.jupiter.api.condition.OS
import org.junit.jupiter.params.ParameterizedTest
import org.junitpioneer.jupiter.cartesian.CartesianTest
/**
* You need 3 things: [TestApplicationWithEel],[EelSource] and [EelHolder].
*/
@TestApplicationWithEel(atLeastOneRemoteEelRequired = false)
@TestApplicationWithEel(osesMayNotHaveRemoteEels = [OS.WINDOWS, OS.LINUX, OS.MAC])
class EelParametrizedShowCaseTest {
@ParameterizedTest
@EelSource
@@ -16,13 +16,14 @@ import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.condition.OS
import org.junit.jupiter.params.ParameterizedTest
/**
* How to use [ExecService].
* To exec this test against remote eels, you need `intellij.platform.ijent.testFramework` in classpath (exists on TC)
*/
@TestApplicationWithEel(atLeastOneRemoteEelRequired = false)
@TestApplicationWithEel(osesMayNotHaveRemoteEels = [OS.WINDOWS, OS.LINUX, OS.MAC])
class ExecServiceShowCaseTest {
@ParameterizedTest