blob: 0031ca2c5478d3424f04d6e4cd89b9962b52625f [file] [log] [blame]
// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize.logging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class AndroidLogRemovalTest extends TestBase {
private final int maxRemovedAndroidLogLevel;
private final TestParameters parameters;
@Parameters(name = "{1}, log level: {0}")
public static List<Object[]> data() {
return buildParameters(
ImmutableList.of(1, 2, 3, 4, 5, 6, 7),
getTestParameters().withAllRuntimesAndApiLevels().build());
}
public AndroidLogRemovalTest(int maxRemovedAndroidLogLevel, TestParameters parameters) {
this.maxRemovedAndroidLogLevel = maxRemovedAndroidLogLevel;
this.parameters = parameters;
}
@Test
public void test() throws Exception {
Path libraryFile =
testForR8(parameters.getBackend())
.addProgramClassFileData(
transformer(Log.class).setClassDescriptor("Landroid/util/Log;").transform())
.addKeepAllClassesRule()
.setMinApi(parameters.getApiLevel())
.compile()
.writeToZip();
testForR8(parameters.getBackend())
.addProgramClassFileData(
transformer(TestClass.class)
.transformMethodInsnInMethod(
"main",
(opcode, owner, name, descriptor, isInterface, continuation) ->
continuation.visitMethodInsn(
opcode,
owner.endsWith("$Log") ? "android/util/Log" : owner,
name,
descriptor,
isInterface))
.transform())
.addLibraryFiles(libraryFile, runtimeJar(parameters.getBackend()))
.addKeepMainRule(TestClass.class)
.addKeepRules("-maximumremovedandroidloglevel " + maxRemovedAndroidLogLevel)
.setMinApi(parameters.getApiLevel())
.compile()
.addRunClasspathFiles(libraryFile)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(getExpectedOutputForMaxLogLevel());
}
private String getExpectedOutputForMaxLogLevel() {
switch (maxRemovedAndroidLogLevel) {
case 1:
return StringUtils.join(
"",
StringUtils.times(StringUtils.lines("[R8] VERBOSE."), 2),
StringUtils.times(StringUtils.lines("[R8] DEBUG."), 2),
StringUtils.times(StringUtils.lines("[R8] INFO."), 2),
StringUtils.times(StringUtils.lines("[R8] WARN."), 2),
StringUtils.times(StringUtils.lines("[R8] ERROR."), 2),
StringUtils.times(StringUtils.lines("[R8] ASSERT."), 2));
case 2:
return StringUtils.join(
"",
StringUtils.times(StringUtils.lines("[R8] DEBUG."), 2),
StringUtils.times(StringUtils.lines("[R8] INFO."), 2),
StringUtils.times(StringUtils.lines("[R8] WARN."), 2),
StringUtils.times(StringUtils.lines("[R8] ERROR."), 2),
StringUtils.times(StringUtils.lines("[R8] ASSERT."), 2));
case 3:
return StringUtils.join(
"",
StringUtils.times(StringUtils.lines("[R8] INFO."), 2),
StringUtils.times(StringUtils.lines("[R8] WARN."), 2),
StringUtils.times(StringUtils.lines("[R8] ERROR."), 2),
StringUtils.times(StringUtils.lines("[R8] ASSERT."), 2));
case 4:
return StringUtils.join(
"",
StringUtils.times(StringUtils.lines("[R8] WARN."), 2),
StringUtils.times(StringUtils.lines("[R8] ERROR."), 2),
StringUtils.times(StringUtils.lines("[R8] ASSERT."), 2));
case 5:
return StringUtils.join(
"",
StringUtils.times(StringUtils.lines("[R8] ERROR."), 2),
StringUtils.times(StringUtils.lines("[R8] ASSERT."), 2));
case 6:
return StringUtils.join("", StringUtils.times(StringUtils.lines("[R8] ASSERT."), 2));
case 7:
return "";
default:
throw new Unreachable();
}
}
static class TestClass {
public static void main(String[] args) {
Log.v("R8", "VERBOSE.");
if (Log.isLoggable("R8", Log.VERBOSE)) {
System.out.println("[R8] VERBOSE.");
}
Log.d("R8", "DEBUG.");
if (Log.isLoggable("R8", Log.DEBUG)) {
System.out.println("[R8] DEBUG.");
}
Log.i("R8", "INFO.");
if (Log.isLoggable("R8", Log.INFO)) {
System.out.println("[R8] INFO.");
}
Log.w("R8", "WARN.");
if (Log.isLoggable("R8", Log.WARN)) {
System.out.println("[R8] WARN.");
}
Log.e("R8", "ERROR.");
if (Log.isLoggable("R8", Log.ERROR)) {
System.out.println("[R8] ERROR.");
}
Log.wtf("R8", "ASSERT.");
if (Log.isLoggable("R8", Log.ASSERT)) {
System.out.println("[R8] ASSERT.");
}
}
}
public static class Log {
public static final int VERBOSE = 2;
public static final int DEBUG = 3;
public static final int INFO = 4;
public static final int WARN = 5;
public static final int ERROR = 6;
public static final int ASSERT = 7;
public static boolean isLoggable(String tag, int level) {
return true;
}
public static int v(String tag, String message) {
System.out.println("[" + tag + "] " + message);
return 42;
}
public static int d(String tag, String message) {
System.out.println("[" + tag + "] " + message);
return 42;
}
public static int i(String tag, String message) {
System.out.println("[" + tag + "] " + message);
return 42;
}
public static int w(String tag, String message) {
System.out.println("[" + tag + "] " + message);
return 42;
}
public static int e(String tag, String message) {
System.out.println("[" + tag + "] " + message);
return 42;
}
public static int wtf(String tag, String message) {
System.out.println("[" + tag + "] " + message);
return 42;
}
}
}