Finding java_test data dependency

806 views
Skip to first unread message

Paul Johnston

unread,
Jul 13, 2016, 1:25:46 PM7/13/16
to bazel-discuss
Sorry for such a basic question.  I'm trying to find a java.io.File during the context of a java_test.  Here's what I have:

# //java/org/bar/service/BUILD
java_library(
    name = "foo",
    srcs = [
        "FooService.java",
    ],
    deps = [
        "//third_party:foo_support",
    ],
)

java_library(
    name = "tests",
    srcs = [
        "TestFooService.java",
    ],
    deps = [
        ":foo",
        "//third_party:junit4",
    ],
)

java_test(
    name = "test-foo",
    size = "small",
    test_class = "org.bar.service.TestFooService",
    data = [
        # This is the file I want to access during the test
        "test-image.png",
    ],
    runtime_deps = [
        ":foo",
        ":tests",
        "//third_party:junit4",
    ],
)

# //java/org/bar/service/TestFooService.java
package org.bar.service;

import java.io.File;

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;

public class TestFooService {

  FooService foo;

  @Before
  public void setUp() throws Exception {
    foo = new FooService();
  }

  @Test
  public void testDataFile() throws Exception {
    // This assumes that the data file 
    // will be placed in the root of the context 
    // directory where the test is executed (false). 
    File png = new File("test-image.png");
    assertTrue("data file should exist", png.exists());
  }

}

$ bazel test //java/org/bar/service:test-foo

TEST FAILED


What is the correct path or best-practice to access this data dependency file?  I can't seem to find it under the .../test-foo.runfiles/__main__/ tree.  

Paul Johnston

unread,
Jul 13, 2016, 1:45:34 PM7/13/16
to bazel-discuss
I now see that is can access the file via the source path:

new File("java/org/bar/service/test-image.png");

However, my tests then require hardcoded knowledge of the project layout, which seems excessive.  Is this the intended best practice?

itt...@wix.com

unread,
Jul 13, 2016, 10:39:47 PM7/13/16
to bazel-discuss
Just to make sure, you know that you can use "resources" and that gets packaged into the test jar and accessible on the classpath, right?
Might not be what you need but just verifying

Paul Johnston

unread,
Jul 14, 2016, 2:27:18 AM7/14/16
to bazel-discuss, itt...@wix.com
Right, and the "resources" attribute works as I would expect.  What I don't fully grep yet is how the "data" attribute is intended to work and I have not found any java_test examples online that demonstrate it's use.  I guess the lesson is that bazel does not "move" files around, just links them up according to the same namespace of the dependency graph.   I can see how this could avoid different data resources stepping on each other, but I'm not sure that is the rationale.


Looks like the way it to get a data dependency is to lookup the runfiles directory from System.getenv("JAVA_RUNFILES") or System.getenv("TEST_SRCDIR") and then append the full path of the file as it appears within the workspace. If the workspace name has not been defined by the workspace rule, e.g. (workspace(name = "io_bazel"), the default is __main__.
 
Thanks,
Paul 

Kristina Chodorow

unread,
Jul 14, 2016, 4:50:56 AM7/14/16
to Paul Johnston, bazel-discuss, itt...@wix.com
On Thu, Jul 14, 2016 at 2:27 AM, Paul Johnston <pcj...@gmail.com> wrote:
Right, and the "resources" attribute works as I would expect.  What I don't fully grep yet is how the "data" attribute is intended to work and I have not found any java_test examples online that demonstrate it's use.  I guess the lesson is that bazel does not "move" files around, just links them up according to the same namespace of the dependency graph.   I can see how this could avoid different data resources stepping on each other, but I'm not sure that is the rationale.

It also keeps them organized (which is kind of the same idea).  

Not sure if you're aware, but data can take targets, too, so you could put the files in any package you want and say data = ["//some/other:target"].  Note that this won't move the files to the java/org/bar/service directory, you'd have to still reference them under the some/other directory in your test.  But it sounded like you didn't want them under java/org/bar/service/.
 


Looks like the way it to get a data dependency is to lookup the runfiles directory from System.getenv("JAVA_RUNFILES") or System.getenv("TEST_SRCDIR") and then append the full path of the file as it appears within the workspace. If the workspace name has not been defined by the workspace rule, e.g. (workspace(name = "io_bazel"), the default is __main__.

Yes, although if you're just running `bazel test` you should just be able to use the relative path.  `bazel test` cd's to the runfiles directory to run the test.  (Running bazel-bin/java/org/bar/service/test-foo directly does not, though, so using the environment variables for the path prefix is more flexible.)
 
Reply all
Reply to author
Forward
0 new messages