Date: Fri, 29 Mar 2024 15:17:46 +0000 (UTC) Message-ID: <1980139345.1377.1711725466400@34fc92c9345b> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_1376_1478334455.1711725466400" ------=_Part_1376_1478334455.1711725466400 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
OpenJFX contains many JUnit based unit tests that can be run using 'gradl= e test' as part of a build.
There are two primary locations to find the unit tests in the repository= :
In these locations, we have
In a non-modular build, there is nothing really separating the unit test= s and the shims but convention.
A shim is a java class that provides a backdoor into the core classes fo= r testing purposes.They are special in a number of ways:
In the OpenJFX repository, the shims are any test class that does not re= side in the test package.
It is best to keep these shim classes as simple as possible, reserving a= s much of the test logic in the Unit test classes as possible. Sometimes ho= wever, it makes sense to add more than just an accessor method, adding util= ity routines that may be easier to write from within the protected package.=
With modules, the shim classes must live in a package already referenced= in the module-info for the class, even if the package is not public. The a= ddExports option can be used to loosen module restrictions, but not expose = a package that is not already listed.
The unit tests run with the application class loader, and not the extens= ion class loader as the core classes.
With modules, the unit tests run in the "unnamed" module by defaul= t. OpenJFX does not create a "test" module containing the tests.
All unit tests must be:
Optional Tests with gradle toggles.
All unit tests must:
When creating a new unit test, think about some of the special cases lis= ted above and talk to the team about any special needs.
Currently all of the Robot based tests are in systemTests, and must live= in the test.robot package.
Often a single test can be run for debugging using the --tests option to= gradle:
gradle -PFULL_TEST=3Dtrue -PUSE_ROBOT=3Dtrue :systemTests:test --tests t= est.robot.javafx.embed.swing.RT32570Test
In this example, we want to run a single test in systemTests, which need= s to be enabled with FULL_TEST
There are times when a Unit test must be conditional or disabled. Here a= re some of the tricks for doing that.
The annotation @Ignore("bug_id") is used to disable a uni= t test on all platforms,
Unstable tests can be toggled using the conditions from within the test:=
assumeTrue(Boolean.getBoolean("unstable.test"));
Some tests are platform specific. These can be toggled with a line like = this:
assumeTrue(PlatformUtil.isMac() || PlatformUtil.isWindows());<= /pre>Classpath
Gradle configures the classpath for each of the test modules. This class= path includes
The dependent modules test classes are rarely used, but do contain items= like the stub toolkit, so must be included.
With the addition of modules in JDK9, there are some additional details = that must be understood when dealing with the unit tests.
It helps to review the module-info.java for the module you are working o= n to understand the visibility of the module.
The unit tests run in the "unnamed" module, and so by default can only s= ee the public packages like this one:
exports javafx.beans;
many packages are not exported as public like this one:
exports com.sun.javafx to
javafx.controls,
javafx.graphics;
To access a class in this package, we will need to use an addExport option =
to override the default package protections for the test. Also note that pa=
ckage specifications do not include any sub packages - each must be explici=
tly mentioned.
Any packages not mentioned in the module info cannot be used for a shim,= because the JDK does not allow addExport of unreferenced packages. In thes= e cases, you will have to get clever with your shims, placing the test shim= in a visible package, perhaps calling a second layer of shim in a hidden p= ackage.
Each of the build modules in OpenJFX has an addExports file that is impo= rted using @argfile into the test invocation. The addExports file contains = entries that export packages that are not public so that the unit tests in = the unnamed module can see them. Here is an excerpt from one of the files:<= /p>
-XaddExports:javafx.base/com.sun.javafx.collections=3DALL-UNNAMED<= /pre>-XaddExports:javafx.base/com.sun.javafx.property=3DALL-UNNAMED-XaddExports:javafx.base/com.sun.javafx=3DALL-UNNAMED-XaddExports:javafx.base/com.sun.javafx.event=3DALL-UNNAMEDAnd example error, that indicates a missing export:
java.lang.IllegalAccessError: class test.= javafx.beans.Person (in unnamed module @0x22a67b4) cannot access class com.= sun.javafx.property.PropertyReference (in module javafx.base) because modul= e javafx.base does not export com.sun.javafx.property to unnamed module @0x= 22a67b4
Building an Xpatch
As part of the modular test build, we need to create a directory contain= ing the freshly built core classes with the shim classes added in. This com= bined mix of classes can be used with the Xpatch command to override the mo= dules in the JDK.
In the OpenJFX build, this results in -Xpatch:build/testing/modules
NOTE: Xpatch does not override module-info.
Finding our shared li= braries
By default, java will look for the module shared libraries in the JDK, w= hich may mean problems if was are trying to use the libraries we just built= . To access those libraries, we need to use -Djava.library.path=3Dbuild/sdk= /lib/_the_right_arch_ to find them
Capturing our classpath= h3>
During the gradle test task, an @argfile form of the test classpath is c= reated for each of the modules. This can be used for reference or with manu= al command lines. An example of this file is: build/testing/classpath_g= raphics.txt.
GradleJUnitWorker
Gradle 2.11 does not understand JDK 9 modules. Normally, gradle uses its= own JUnit worker to process the test environment, particularly the classpa= th before running each of the tests. GradleJUnitWorker was created to worka= round many of the issues that were encountered. This workaround is launched= by gradle, and it in turn launches the gradle JUnit worker with the approp= riate JDK9 modular arguments.
Toggling worker.debug
In build.gradle, there is a toggle that can be used to create additional= output from GradleJUnitWorker showing the command lines used to launch tes= ts. This currently affects GradleJUnitWorker.java and the system Sandb= ox tests. Modify this line (temporarily), and run tests with the gradle -in= fo option. (The -info option to gradle enables it to pass through stdout/st= derr from the worker process).
systemProperties 'worker.debug': false
Security
If a security manager is used, extra permissions are required with Xpatc= h. All of the classes in the Xpatch are treated as outside the module for t= he purposes of security grants.
For our current JUnit tests, this only applies to the Sandbox tests in := systemtests. To permit the Xpatch classes to operate properly, we generate = a java.policy file for the core FX classes in the Xpatch modules. This java= .policy file (build/testing/java.patch.policy) can be used standalone if no= additional permissions are needed, or must be combined with the desired ad= ditional permissions to form a single java.policy file. The Sandbox tests c= ombine the permissions in the text file indicated by the property worker.pa= tch.policy with the test permissions, and use the resulting file when invok= ing the test app.
An example mo= dular manual command line
The following is an example command line that can run a junit test from = within a built Linux OpenJFX modular tree. This can be useful when debuggin= g a single test class:
jdk-9/bin/java \-Xpatch:build/testing/modules \@tests/system/src/test/addExports \@build/testing/classpath_systemTests.txt \-Djava.library.path=3Dbuild/sdk/lib/amd64 \org.junit.runner.JUnitCore \test.sandbox.SandboxAppTest