On 3/06/2017 5:10 AM, Igor Ignatyev wrote:

On Jun 2, 2017, at 9:14 AM, Ioi Lam <ioi....@oracle.com> wrote:

On 6/2/17 8:44 AM, Ioi Lam wrote:

On 6/2/17 6:40 AM, Chris Hegarty wrote:
On 02/06/17 00:14, Ioi Lam wrote:
...

The gem is hidden in the compile.0.jta file. It contains something like:

      -sourcepath <blahblah>:/jdk/foobar/test/lib:<blahblah>

So if my test refers to a class under /test/lib, such as
jdk.test.lib.process.ProcessTools, javac will be able to locate it under
/jdk/foobar/test/lib/jdk/test/lib/process/ProcessTools.java, and will
build it automatically.

So really, there's no reason why the test must explicitly do an @build
of the library classes that it uses.

Sure, you're relying on the implicit compilation of dependencies
by javac. Look at the output, where it compiles the library
classes to.  It is part of the classes directory for the
individual test. That means that the library classes will need
to be compiled many many times.  The @build tag will compile
the library classes to a common output directory, where they
can be reused ( unless I'm missing something ).

-Chris.
Yes, @build will compile classes so that they can be reused. But why should it 
be the responsibility of every test to do this?

To reuse my malloc metaphore -- is it reasonable for every program that uses 
malloc to explicitly build libc?

By the way, jtreg arranges the output directory of the test by the directory 
they sit in, so

  jdk/test/foo/bar/XTest.java
  jdk/test/foo/bar/YTest.java

will all output their .class files to the same directory. Therefore, the amount 
of duplicated classes is not as bad as you might think. We've been omitting the 
@build tags in the hotspot tests and we haven't seen any problems.

- Ioi
To avoid repeat compilation of the library classes, a more reasonable solution 
would be:

[1] Before test execution -- scan all the selected test to find all libraries 
specified by @library tags

[2] Fully compile all the libraries into their own output directories

[3] Then, start execution of the selected tests

unfortunately, it is not that simple, there are at least 2 problems w/ that 
approach:
  1. some of library classes have extra module dependency, e.g. 
jdk.test.lib.management.* depend on jdk.management module, ExtendedRobot (from 
jdk/test/testlibrary) depends on java.desktop. so compiling the whole library 
will require extra module dependency, which might be unneeded for the selected 
tests, as a result we won't be able to run these tests on configurations w/ 
limited module set.
  2. to make our tests packagefull, we had to add '@library /' to many 
hotspot/test/compiler tests, so we will have to compile all files from 
hotspot/test.

my take on all of this is that determination of output directory for classes is 
buggy, it uses directory of a @build or @run target to decide where put all 
produced classes files, but it should have mapping between source and 
destination paths instead, so all classes from jdk/test/foo/bar/ will go to a 
test scratch directory and all classes from /test/lib/ (assuming they are 
declared as @library) and /jdk/test/lib/ to different common directories which 
will be later added to classpath for the tests which use these libraries.

But unless you explicitly compile the library classes you can't control where the class files are placed. The tests are compiled with a "-d" directive, so all classes, directly and implicitly compiled will be relative to that directory based on their package. If every test were declared in a package based on the source arrangement then jtreg would be able to use a common output directory.

Neither suggested approach seems a great solution to me. Implicit compilation wastes effort rebuilding the libraries. Explicit compilation is instrusive and difficult to get right - and I have no idea how to get the module dependency stuff sorted out.

Maybe the design flaw here is attempting to combine a test library with the tests that use it. You either want it to be a binary library jtreg can be pointed at, or you need a way to tell jtreg to build the library first and then use. But IIUC jtreg isn't set up to handle that - but it could be handled by running jtreg via make.

My 2c.

David

Thanks,
-- Igor

Reply via email to