tests: introduce BazelTestUtil to interface with running tests under Bazel

use BazelTestUtil to find mock JDKs in IdeaTestUtil

GitOrigin-RevId: 6061cf057e53dc707b7a2ab308e2cca3bf6bf9c9
This commit is contained in:
Leonid Shalupov
2025-07-08 23:18:10 +00:00
committed by intellij-monorepo-bot
parent 04ef79fdaf
commit 4fc4f7588e
4 changed files with 109 additions and 1 deletions
+2
View File
@@ -112,6 +112,8 @@ def jps_test(name, jvm_flags = [], runtime_deps = [], args = [], **kwargs):
data = [
# so com.intellij.tests.JUnit5BazelRunner.guessBazelWorkspaceDir will find a real workspace root
"@community//:intellij.idea.community.main.iml",
# required for com.intellij.openapi.projectRoots.impl.JavaSdkImpl.internalJdkAnnotationsPath
"@community//java:mockJDK",
],
use_testrunner = False,
**kwargs
+11
View File
@@ -0,0 +1,11 @@
filegroup(
name = "mockJDK",
srcs = glob([
"mockJDK-1.4/**",
"mockJDK-1.7/**",
"mockJDK-1.8/**",
"mockJDK-1.9/**",
"jdkAnnotations/**",
], allow_empty = False),
visibility = ["//visibility:public"],
)
@@ -18,6 +18,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.common.BazelTestUtil;
import com.intellij.testFramework.fixtures.MavenDependencyUtil;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.PathUtil;
@@ -266,7 +267,16 @@ public final class IdeaTestUtil {
}
private static @NotNull File getPathForJdkNamed(@NotNull String name) {
return new File(PlatformTestUtil.getCommunityPath(), "java/" + name);
// Bazel-provided test dependencies, from runfiles tree
if (BazelTestUtil.isUnderBazelTest()) {
return BazelTestUtil.findRunfilesDirectoryUnderCommunityOrUltimate("java/" + name).toFile();
}
File file = new File(PlatformTestUtil.getCommunityPath(), "java/" + name);
if (!file.isDirectory()) {
throw new RuntimeException("Can't find JDK directory for " + name + " at " + file);
}
return file;
}
public static void addWebJarsToModule(@NotNull Module module) {
@@ -0,0 +1,85 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.testFramework.common
import org.jetbrains.annotations.ApiStatus
import java.nio.file.Path
import kotlin.io.path.absolute
import kotlin.io.path.isDirectory
@ApiStatus.Experimental
object BazelTestUtil {
// see https://bazel.build/reference/test-encyclopedia#initial-conditions
// also https://leimao.github.io/blog/Bazel-Test-Outputs/
private const val TEST_SRCDIR_ENV_NAME = "TEST_SRCDIR"
private const val TEST_UNDECLARED_OUTPUTS_DIR_ENV_NAME = "TEST_UNDECLARED_OUTPUTS_DIR"
@JvmStatic
val isUnderBazelTest: Boolean =
System.getenv(TEST_SRCDIR_ENV_NAME) != null &&
System.getenv(TEST_UNDECLARED_OUTPUTS_DIR_ENV_NAME) != null
/**
* Absolute path to the base of the runfiles tree (your test dependencies too),
* see [Test encyclopedia](https://bazel.build/reference/test-encyclopedia#initial-conditions)
*/
@JvmStatic
val bazelTestRunfilesPath: Path by lazy {
val value = System.getenv(TEST_SRCDIR_ENV_NAME)
if (value == null) {
error("Not running under `bazel test` because $TEST_SRCDIR_ENV_NAME env is not set. Check isUnderBazelTest first.")
}
val path = Path.of(value).absolute()
if (!path.isDirectory()) {
error("Bazel test env '$TEST_SRCDIR_ENV_NAME' points to non-directory: $path")
}
path
}
@JvmStatic
val bazelUndeclaredTestOutputsPath: Path by lazy {
val value = System.getenv(TEST_UNDECLARED_OUTPUTS_DIR_ENV_NAME)
if (value == null) {
error("Not running under `bazel test` because $TEST_UNDECLARED_OUTPUTS_DIR_ENV_NAME env is not set. Check isUnderBazelTest first.")
}
val path = Path.of(value).absolute()
if (!path.isDirectory()) {
error("Bazel test env '$TEST_UNDECLARED_OUTPUTS_DIR_ENV_NAME' points to non-directory: $path")
}
path
}
/**
* Tests under community root may run in community (OSS) or in the ultimate monorepo context.
*
* Under ultimate monorepo Bazel project, workspace for test dependencies is named `community+`,
* while when run under community Bazel project, it's named `_main`.
*
* This function finds `relativePath` under one of them, depending on current project.
* It fails when the directory can't be found or there is an ambiguity.
*
* see https://bazel.build/reference/be/common-definitions#typical-attributes (check `data`)
*
* see https://bazel.build/reference/test-encyclopedia#initial-conditions
*/
@JvmStatic
fun findRunfilesDirectoryUnderCommunityOrUltimate(relativePath: String): Path {
val root1 = bazelTestRunfilesPath.resolve("community+").resolve(relativePath)
val root2 = bazelTestRunfilesPath.resolve("_main").resolve(relativePath)
val root1exists = root1.isDirectory()
val root2exists = root2.isDirectory()
if (!root1exists && !root2exists) {
error("Cannot find runfiles directory $relativePath under community+ or _main. " +
"TEST_SRCDIR (runfiles root) = ${bazelTestRunfilesPath}. " +
"Tried $root1 and $root2. " +
"Please check that you passed this directory via data attribute of test rule")
}
if (root1exists && root2exists) {
error("Both $root1 and $root2 exist. " +
"Meaning $relativePath is available both under community and ultimate roots. " +
"This ambitious setup might cause problems. " +
"Please remove $root1 or $root2 or use a different relative path for test rule")
}
return if (root1exists) root1 else root2
}
}