@@ -34,90 +34,50 @@ class BlazeTestSystemProperties {
3434
3535 private BlazeTestSystemProperties () {}
3636
37- /** The absolute path to the runfiles directory. */
38- private static final String RUNFILES_PATH = TestUtils .getUserValue ("TEST_SRCDIR" );
39-
4037 /** Sets up the necessary system properties for running IntelliJ tests via blaze/bazel. */
4138 public static void configureSystemProperties () {
42- File sandbox = new File (TestUtils .getTmpDirFile (), "_intellij_test_sandbox" );
39+ final var sandbox = new File (TestUtils .getTmpDirFile (), "_intellij_test_sandbox" );
40+
41+ redirectIdePathsToSandbox (sandbox );
42+ linkSdkDirectoriesIntoSandbox ();
43+ configurePluginCompatibility ();
44+ relaxFileSystemChecks ();
45+
46+ setIfEmpty ("idea.classpath.index.enabled" , "false" );
47+ setIfEmpty ("idea.force.use.core.classloader" , "true" );
48+ }
4349
50+ /** Points all IDE state (config, caches, logs, preferences, home) at the test sandbox. */
51+ private static void redirectIdePathsToSandbox (File sandbox ) {
4452 setSandboxPath ("idea.home.path" , new File (sandbox , "home" ));
4553 setSandboxPath ("idea.config.path" , new File (sandbox , "config" ));
4654 setSandboxPath ("idea.system.path" , new File (sandbox , "system" ));
47- String testUndeclaredOutputsDir = System .getenv ("TEST_UNDECLARED_OUTPUTS_DIR" );
55+
56+ final var testUndeclaredOutputsDir = System .getenv ("TEST_UNDECLARED_OUTPUTS_DIR" );
4857 if (testUndeclaredOutputsDir != null ) {
4958 setSandboxPath ("idea.log.path" , new File (testUndeclaredOutputsDir , "logs" ));
5059 }
5160
5261 setSandboxPath ("java.util.prefs.userRoot" , new File (sandbox , "userRoot" ));
5362 setSandboxPath ("java.util.prefs.systemRoot" , new File (sandbox , "systemRoot" ));
5463
55- // On the radler/Rider code path the platform accesses <idea.home.path>/lib (and
56- // /bin) very early during application load, before any test setUp would run. Since
57- // idea.home.path points at the empty sandbox, link those dirs to the real SDK.
58- Path sdkRoot = findSdkRoot ();
59- linkSandboxDir (sdkRoot , "bin" , Path .of (PathManager .getBinPath ()));
60- linkSandboxDir (sdkRoot , "lib" , Path .of (PathManager .getLibPath ()));
61-
62- setIfEmpty ("idea.classpath.index.enabled" , "false" );
63-
64- // Some plugins have a since-build and until-build restriction, so we need
65- // to update the build number here
66- String buildNumber = readApiVersionNumber ();
67- if (buildNumber == null ) {
68- buildNumber = BuildNumber .currentVersion ().asString ();
69- }
70- setIfEmpty ("idea.plugins.compatible.build" , buildNumber );
71- setIfEmpty (PlatformUtils .PLATFORM_PREFIX_KEY , determinePlatformPrefix (buildNumber ));
72-
73- // b/166052760: Early in the android studio initialization, it accesses the user's home
74- // directory for retrieving some analytics settings, and to also set up an SDK from
75- // ~/Android/sdk, both of which it shouldn't be doing during testing. To fix this, we reset home
76- // directory to point to a temporary directory. (Blaze may be doing this in general, so this
77- // is more useful for bazel).
64+ // Reset the home directory to a temporary location so tests can neither read nor
65+ // write the real user home (e.g. analytics settings or a local SDK under ~/Android).
7866 System .setProperty ("user.home" , new File (sandbox , "userhome" ).getAbsolutePath ());
79-
80- // Tests fail if they access files outside of the project roots and other system directories.
81- // When the class path contains jars which contain `kotlin` packages the `BuiltinsVirtualFileProviderBaseImpl`
82- // also access jars from the class path. Therefore, this checks needs either to be disabled or
83- // the specific jars need to be added to the `VfsRootAccess` allow list.
84- System .setProperty ("NO_FS_ROOTS_ACCESS_CHECK" , "true" );
85-
86- setIfEmpty ("idea.force.use.core.classloader" , "true" );
8767 }
8868
89- @ Nullable
90- private static String determinePlatformPrefix (String buildNumber ) {
91- if (buildNumber .startsWith ("IU" )) { // IntelliJ Ultimate
92- return null ;
93- } else if (buildNumber .startsWith ("IC" )) { // IntelliJ Community
94- return "Idea" ;
95- } else if (buildNumber .startsWith ("CL" )) { // CLion
96- return "CLion" ;
97- } else {
98- throw new RuntimeException ("Unable to determine platform prefix for build: " + buildNumber );
99- }
100- }
101-
102- @ Nullable
103- private static String readApiVersionNumber () {
104- String apiVersionFilePath = System .getProperty ("blaze.idea.api.version.file" );
105- String runfilesWorkspaceRoot = System .getProperty ("user.dir" );
106- if (apiVersionFilePath == null ) {
107- throw new RuntimeException ("No api_version_file found in runfiles directory" );
108- }
109- if (runfilesWorkspaceRoot == null ) {
110- throw new RuntimeException ("Runfiles workspace root not found" );
111- }
112- final var apiVersionFile = new File (runfilesWorkspaceRoot , apiVersionFilePath );
113- if (!apiVersionFile .canRead ()) {
114- return null ;
115- }
116- try {
117- return com .google .common .io .Files .asCharSource (apiVersionFile , StandardCharsets .UTF_8 ).readFirstLine ();
118- } catch (IOException e ) {
119- throw new RuntimeException (e );
120- }
69+ /**
70+ * Links the SDK {@code bin} and {@code lib} directories into the sandbox home.
71+ *
72+ * <p>On the radler/Rider code path the platform accesses {@code <idea.home.path>/lib} (and {@code
73+ * /bin}) very early during application load, before any test setUp would run. Since {@code
74+ * idea.home.path} points at the empty sandbox, those directories have to be linked to the real
75+ * SDK beforehand.
76+ */
77+ private static void linkSdkDirectoriesIntoSandbox () {
78+ final var sdkRoot = findSdkRoot ();
79+ linkSandboxDir (sdkRoot , "bin" , Path .of (PathManager .getBinPath ()));
80+ linkSandboxDir (sdkRoot , "lib" , Path .of (PathManager .getLibPath ()));
12181 }
12282
12383 private static Path findSdkRoot () {
@@ -150,6 +110,67 @@ private static void linkSandboxDir(Path sdkRoot, String dirName, Path link) {
150110 }
151111 }
152112
113+ /**
114+ * Reports the build number (and matching platform prefix) the tests should use, so plugins with a
115+ * since-build/until-build restriction are considered compatible.
116+ */
117+ private static void configurePluginCompatibility () {
118+ final var buildNumber = resolveBuildNumber ();
119+ setIfEmpty ("idea.plugins.compatible.build" , buildNumber );
120+ setIfEmpty (PlatformUtils .PLATFORM_PREFIX_KEY , determinePlatformPrefix (buildNumber ));
121+ }
122+
123+ private static String resolveBuildNumber () {
124+ final var apiVersion = readApiVersionNumber ();
125+ return apiVersion != null ? apiVersion : BuildNumber .currentVersion ().asString ();
126+ }
127+
128+ @ Nullable
129+ private static String readApiVersionNumber () {
130+ final var apiVersionFilePath = System .getProperty ("blaze.idea.api.version.file" );
131+ if (apiVersionFilePath == null ) {
132+ throw new RuntimeException ("No api_version_file found in runfiles directory" );
133+ }
134+
135+ final var runfilesWorkspaceRoot = System .getProperty ("user.dir" );
136+ if (runfilesWorkspaceRoot == null ) {
137+ throw new RuntimeException ("Runfiles workspace root not found" );
138+ }
139+
140+ final var apiVersionFile = Path .of (runfilesWorkspaceRoot , apiVersionFilePath );
141+ if (!Files .isReadable (apiVersionFile )) {
142+ return null ;
143+ }
144+
145+ try {
146+ return Files .readString (apiVersionFile , StandardCharsets .UTF_8 ).lines ().findFirst ().orElse (null );
147+ } catch (IOException e ) {
148+ throw new RuntimeException (e );
149+ }
150+ }
151+
152+ @ Nullable
153+ private static String determinePlatformPrefix (String buildNumber ) {
154+ if (buildNumber .startsWith ("IU" )) { // IntelliJ Ultimate
155+ return null ;
156+ } else if (buildNumber .startsWith ("IC" )) { // IntelliJ Community
157+ return "Idea" ;
158+ } else if (buildNumber .startsWith ("CL" )) { // CLion
159+ return "CLion" ;
160+ } else {
161+ throw new RuntimeException ("Unable to determine platform prefix for build: " + buildNumber );
162+ }
163+ }
164+
165+ /**
166+ * Disables the VfsRootAccess check. Tests otherwise fail when accessing files outside the project
167+ * roots; in particular {@code BuiltinsVirtualFileProviderBaseImpl} accesses class path jars that
168+ * contain {@code kotlin} packages, which would need to be added to the allow list instead.
169+ */
170+ private static void relaxFileSystemChecks () {
171+ System .setProperty ("NO_FS_ROOTS_ACCESS_CHECK" , "true" );
172+ }
173+
153174 private static void setSandboxPath (String property , File path ) {
154175 path .mkdirs ();
155176 setIfEmpty (property , path .getPath ());
0 commit comments