| // Copyright 2019 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.devtools.build.lib.outputfilter; |
| |
| import static org.junit.Assert.fail; |
| |
| import com.google.common.base.Joiner; |
| import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase; |
| import com.google.devtools.build.lib.buildtool.util.TestWorkspaceStatusModule; |
| import com.google.devtools.build.lib.events.Event; |
| import com.google.devtools.build.lib.events.EventCollector; |
| import com.google.devtools.build.lib.events.EventKind; |
| import com.google.devtools.build.lib.runtime.BlazeModule; |
| import com.google.devtools.build.lib.runtime.BlazeRuntime; |
| import com.google.devtools.build.lib.runtime.CommandEnvironment; |
| import com.google.devtools.build.lib.testutil.Suite; |
| import com.google.devtools.build.lib.testutil.TestSpec; |
| import com.google.devtools.build.lib.vfs.Path; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** Tests for the {@code --output_filter} option. */ |
| @TestSpec(size = Suite.MEDIUM_TESTS) |
| @RunWith(JUnit4.class) |
| public class OutputFilterTest extends BuildIntegrationTestCase { |
| private EventCollector stderr = new EventCollector(EventKind.STDERR); |
| private Path workspaceScript; |
| |
| // Cast warnings are silenced by default. |
| private void enableCastWarnings() throws Exception { |
| addOptions("--javacopt=\"-Xlint:cast\""); |
| } |
| |
| // Deprecation warnings are silenced by default. |
| private void enableDeprecationWarnings() throws Exception { |
| addOptions("--javacopt=\"-Xlint:deprecation\""); |
| } |
| |
| @Override |
| protected BlazeModule getBuildInfoModule() { |
| return TestWorkspaceStatusModule.getModule(); |
| } |
| |
| @Override |
| protected BlazeRuntime.Builder getRuntimeBuilder() throws Exception { |
| return super.getRuntimeBuilder().addBlazeModule(new OutputFilteringModule()); |
| } |
| |
| @Before |
| public final void writeFiles() throws Exception { |
| write("java/a/BUILD", |
| "java_library(name = 'a',", |
| " srcs = ['A.java']," + |
| " deps = ['//java/b'])"); |
| write("java/a/A.java", |
| "package a;", |
| "public class A {", |
| " public static void a() { b.B.b(); }", |
| "}"); |
| write("java/b/BUILD", |
| "java_library(name = 'b',", |
| " srcs = ['B.java']," + |
| " deps = ['//java/c'])"); |
| write("java/b/B.java", |
| "package b;", |
| "public class B {", |
| " @Deprecated public static void b() {}", |
| " public static void x() { c.C.c(); }", |
| "}"); |
| write("java/c/BUILD", |
| "java_library(name = 'c',", |
| " srcs = ['C.java'])"); |
| write("java/c/C.java", |
| "package c;", |
| "public class C {", |
| " @Deprecated public static void c() {}", |
| "}"); |
| write("java/d/BUILD", |
| "java_library(name = 'd',", |
| " srcs = ['D.java'],", |
| " deps = ['//java/e'])"); |
| write( |
| "java/d/D.java", |
| "package d;", |
| "import java.lang.Integer;", |
| "import java.util.ArrayList;", |
| "public class D {", |
| " public static void d() {", |
| " int i = (int) 0;", |
| " e.E.e();", |
| " }", |
| "}"); |
| write("java/e/BUILD", |
| "java_library(name = 'e',", |
| " srcs = ['E.java'])"); |
| write( |
| "java/e/E.java", |
| "package e;", |
| "import java.lang.Integer;", |
| "import java.util.LinkedList;", |
| "public class E {", |
| " public static void e() {", |
| " int i = (int) 0;", |
| " }", |
| "}"); |
| write("javatests/a/BUILD", |
| "java_library(name = 'a',", |
| " srcs = ['ATest.java']," + |
| " deps = ['//java/a', '//javatests/b'])"); |
| write("javatests/a/ATest.java", |
| "package a;", |
| "public class ATest {", |
| " public static void aTest() { a.A.a(); }", |
| "}"); |
| write("javatests/b/BUILD", |
| "java_library(name = 'b',", |
| " srcs = ['BTest.java']," + |
| " deps = ['//java/b', '//javatests/c'])"); |
| write("javatests/b/BTest.java", |
| "package b;", |
| "public class BTest {", |
| " public static void bTest() { c.CTest.c(); }", |
| "}"); |
| write("javatests/c/BUILD", |
| "java_library(name = 'c',", |
| " srcs = ['CTest.java'])"); |
| write("javatests/c/CTest.java", |
| "package c;", |
| "public class CTest {", |
| " @Deprecated public static void c() {}", |
| "}"); |
| write("javatests/d/BUILD", |
| "java_library(name = 'd',", |
| " srcs = ['DTest.java'],", |
| " deps = ['//java/d', '//javatests/e'])"); |
| write("javatests/d/DTest.java", |
| "package d;", |
| "public class DTest {", |
| " public static void dTest() { d.D.d(); }", |
| "}"); |
| write("javatests/e/BUILD", |
| "java_library(name = 'e',", |
| " srcs = ['ETest.java'])"); |
| write( |
| "javatests/e/ETest.java", |
| "package e;", |
| "import java.lang.Integer;", |
| "import java.util.LinkedList;", |
| "public class ETest {", |
| " public static void eTest() {", |
| " int i = (int) 0;", |
| " }", |
| "}"); |
| workspaceScript = write("wrk", "echo STATUS_CMD_HAS_RUN >&2"); |
| workspaceScript.setExecutable(true); |
| |
| // Always enable cast warnings. |
| enableCastWarnings(); |
| } |
| |
| @Test |
| public void testExplicitFilter() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--output_filter=^//java/a"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/a"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertNoEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testExplicitFilterNoJavacoptOverride() throws Exception { |
| addOptions("--output_filter=^//java/d"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/d"); |
| |
| assertEvent("D.java:6: warning: [cast] redundant cast to int"); |
| assertNoEvent("E.java:6: warning: [cast] redundant cast to int"); |
| } |
| |
| @Test |
| public void testPackagesAOF_A() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/a"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertNoEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_B() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/b"); |
| |
| assertNoEvent(deprecationMessages("b", "B", "b")); |
| assertEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_C() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/c"); |
| |
| assertNoEvent(deprecationMessages("b", "B", "b")); |
| assertNoEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_D() throws Exception { |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/d"); |
| |
| assertEvent("D.java:6: warning: [cast] redundant cast to int"); |
| assertNoEvent("E.java:6: warning: [cast] redundant cast to int"); |
| } |
| |
| @Test |
| public void testPackagesAOF_AB() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/a", "//java/b"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_AC() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/a", "//java/c"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertNoEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_BC() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/b", "//java/c"); |
| |
| assertNoEvent(deprecationMessages("b", "B", "b")); |
| assertEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_ABC() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/a", "//java/b", "//java/c"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_JavaTestsA() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//javatests/a"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertNoEvent(deprecationMessages("c", "C", "c")); |
| assertNoEvent(deprecationMessages("c", "CTest", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_JavaTestsAB() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//javatests/a", "//java/b"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertEvent(deprecationMessages("c", "C", "c")); |
| assertEvent(deprecationMessages("c", "CTest", "c")); |
| } |
| |
| @Test |
| public void testPackagesAOF_JavaTestsD() throws Exception { |
| addOptions("--auto_output_filter=packages"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//javatests/d"); |
| |
| assertEvent("D.java:6: warning: [cast] redundant cast to int"); |
| assertNoEvent("E.java:6: warning: [cast] redundant cast to int"); |
| assertNoEvent("ETest.java:6: warning: [cast] redundant cast to int"); |
| } |
| |
| @Test |
| public void testStatusCmdPrinted() throws Exception { |
| addOptions("--auto_output_filter=packages", |
| "--workspace_status_command=" + workspaceScript.getPathString()); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//javatests/a", "//java/b"); |
| assertEvent("STATUS_CMD_HAS_RUN"); |
| |
| addOptions("--auto_output_filter=subpackages", |
| "--workspace_status_command=" + workspaceScript.getPathString()); |
| env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//javatests/a", "//java/b"); |
| assertEvent("STATUS_CMD_HAS_RUN"); |
| } |
| |
| @Test |
| public void testEmptyFilter() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--output_filter="); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/a"); |
| |
| assertEvent(deprecationMessages("b", "B", "b")); |
| assertEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| @Test |
| public void testNoMatchFilter() throws Exception { |
| enableDeprecationWarnings(); |
| addOptions("--output_filter=DONT_MATCH"); |
| CommandEnvironment env = runtimeWrapper.newCommand(); |
| env.getReporter().addHandler(stderr); |
| buildTarget("//java/a"); |
| |
| assertNoEvent(deprecationMessages("b", "B", "b")); |
| assertNoEvent(deprecationMessages("c", "C", "c")); |
| } |
| |
| private void assertEvent(String... choices) { |
| for (Event event : stderr) { |
| for (String msg : choices) { |
| if (event.getMessage().contains(msg)) { |
| return; |
| } |
| } |
| } |
| |
| fail(String.format("Expected one of [%s] in output: %s", |
| Joiner.on(',').join(choices), |
| Joiner.on('\n').join(stderr) |
| )); |
| } |
| |
| private void assertNoEvent(String... choices) { |
| for (Event event : stderr) { |
| for (String msg : choices) { |
| if (event.getMessage().contains(msg)) { |
| fail("Event '" + msg + "' was found in output: \n" + Joiner.on('\n').join(stderr)); |
| } |
| } |
| } |
| } |
| |
| private String[] deprecationMessages(String pkg, String clazz, String method) { |
| return new String[] { |
| String.format("%s() in %s.%s has been deprecated", method, pkg, clazz), // javac6 |
| String.format("%s() in %s has been deprecated", method, clazz) // javac7 |
| }; |
| } |
| } |