Merge "ProtoLog improvements"
This commit is contained in:
committed by
Android (Google) Code Review
commit
abb482017a
@@ -23,7 +23,7 @@ option java_multiple_files = true;
|
||||
/* represents a single log entry */
|
||||
message ProtoLogMessage {
|
||||
/* log statement identifier, created from message string and log level. */
|
||||
optional fixed32 message_hash = 1;
|
||||
optional sfixed32 message_hash = 1;
|
||||
/* log time, relative to the elapsed system time clock. */
|
||||
optional fixed64 elapsed_realtime_nanos = 2;
|
||||
/* string parameters passed to the log call. */
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"messages": {
|
||||
"485522692": {
|
||||
"594230385": {
|
||||
"message": "Test completed successfully: %b %d %o %x %e %g %f %% %s.",
|
||||
"level": "ERROR",
|
||||
"group": "TEST_GROUP"
|
||||
"group": "TEST_GROUP",
|
||||
"at": "com\/android\/server\/wm\/ProtoLogGroup.java:94"
|
||||
}
|
||||
},
|
||||
"groups": {
|
||||
|
||||
@@ -110,6 +110,12 @@ public class ProtoLogImpl {
|
||||
getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, messageString, args);
|
||||
}
|
||||
|
||||
/** Returns true iff logging is enabled for the given {@code IProtoLogGroup}. */
|
||||
public static boolean isEnabled(IProtoLogGroup group) {
|
||||
return group.isLogToProto()
|
||||
|| (group.isLogToProto() && getSingleInstance().isProtoEnabled());
|
||||
}
|
||||
|
||||
private static final int BUFFER_CAPACITY = 1024 * 1024;
|
||||
private static final String LOG_FILENAME = "/data/misc/wmtrace/wm_log.pb";
|
||||
private static final String VIEWER_CONFIG_FILENAME = "/system/etc/protolog.conf.json.gz";
|
||||
@@ -222,48 +228,50 @@ public class ProtoLogImpl {
|
||||
os.write(MESSAGE_HASH, messageHash);
|
||||
os.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
|
||||
|
||||
int argIndex = 0;
|
||||
ArrayList<Long> longParams = new ArrayList<>();
|
||||
ArrayList<Double> doubleParams = new ArrayList<>();
|
||||
ArrayList<Boolean> booleanParams = new ArrayList<>();
|
||||
for (Object o : args) {
|
||||
int type = LogDataType.bitmaskToLogDataType(paramsMask, argIndex);
|
||||
try {
|
||||
switch (type) {
|
||||
case LogDataType.STRING:
|
||||
os.write(STR_PARAMS, o.toString());
|
||||
break;
|
||||
case LogDataType.LONG:
|
||||
longParams.add(((Number) o).longValue());
|
||||
break;
|
||||
case LogDataType.DOUBLE:
|
||||
doubleParams.add(((Number) o).doubleValue());
|
||||
break;
|
||||
case LogDataType.BOOLEAN:
|
||||
booleanParams.add((boolean) o);
|
||||
break;
|
||||
if (args != null) {
|
||||
int argIndex = 0;
|
||||
ArrayList<Long> longParams = new ArrayList<>();
|
||||
ArrayList<Double> doubleParams = new ArrayList<>();
|
||||
ArrayList<Boolean> booleanParams = new ArrayList<>();
|
||||
for (Object o : args) {
|
||||
int type = LogDataType.bitmaskToLogDataType(paramsMask, argIndex);
|
||||
try {
|
||||
switch (type) {
|
||||
case LogDataType.STRING:
|
||||
os.write(STR_PARAMS, o.toString());
|
||||
break;
|
||||
case LogDataType.LONG:
|
||||
longParams.add(((Number) o).longValue());
|
||||
break;
|
||||
case LogDataType.DOUBLE:
|
||||
doubleParams.add(((Number) o).doubleValue());
|
||||
break;
|
||||
case LogDataType.BOOLEAN:
|
||||
booleanParams.add((boolean) o);
|
||||
break;
|
||||
}
|
||||
} catch (ClassCastException ex) {
|
||||
// Should not happen unless there is an error in the ProtoLogTool.
|
||||
os.write(STR_PARAMS, "(INVALID PARAMS_MASK) " + o.toString());
|
||||
Slog.e(TAG, "Invalid ProtoLog paramsMask", ex);
|
||||
}
|
||||
} catch (ClassCastException ex) {
|
||||
// Should not happen unless there is an error in the ProtoLogTool.
|
||||
os.write(STR_PARAMS, "(INVALID PARAMS_MASK) " + o.toString());
|
||||
Slog.e(TAG, "Invalid ProtoLog paramsMask", ex);
|
||||
argIndex++;
|
||||
}
|
||||
argIndex++;
|
||||
}
|
||||
if (longParams.size() > 0) {
|
||||
os.writePackedSInt64(SINT64_PARAMS,
|
||||
longParams.stream().mapToLong(i -> i).toArray());
|
||||
}
|
||||
if (doubleParams.size() > 0) {
|
||||
os.writePackedDouble(DOUBLE_PARAMS,
|
||||
doubleParams.stream().mapToDouble(i -> i).toArray());
|
||||
}
|
||||
if (booleanParams.size() > 0) {
|
||||
boolean[] arr = new boolean[booleanParams.size()];
|
||||
for (int i = 0; i < booleanParams.size(); i++) {
|
||||
arr[i] = booleanParams.get(i);
|
||||
if (longParams.size() > 0) {
|
||||
os.writePackedSInt64(SINT64_PARAMS,
|
||||
longParams.stream().mapToLong(i -> i).toArray());
|
||||
}
|
||||
if (doubleParams.size() > 0) {
|
||||
os.writePackedDouble(DOUBLE_PARAMS,
|
||||
doubleParams.stream().mapToDouble(i -> i).toArray());
|
||||
}
|
||||
if (booleanParams.size() > 0) {
|
||||
boolean[] arr = new boolean[booleanParams.size()];
|
||||
for (int i = 0; i < booleanParams.size(); i++) {
|
||||
arr[i] = booleanParams.get(i);
|
||||
}
|
||||
os.writePackedBool(BOOLEAN_PARAMS, arr);
|
||||
}
|
||||
os.writePackedBool(BOOLEAN_PARAMS, arr);
|
||||
}
|
||||
os.end(token);
|
||||
mBuffer.add(os);
|
||||
|
||||
@@ -351,7 +351,7 @@ public class ProtoLogImplTest {
|
||||
ProtoLogData data = readProtoLogSingle(ip);
|
||||
assertNotNull(data);
|
||||
assertEquals(1234, data.mMessageHash.longValue());
|
||||
assertTrue(before < data.mElapsedTime && data.mElapsedTime < after);
|
||||
assertTrue(before <= data.mElapsedTime && data.mElapsedTime <= after);
|
||||
assertArrayEquals(new String[]{"test"}, data.mStrParams.toArray());
|
||||
assertArrayEquals(new Long[]{1L, 2L, 3L}, data.mSint64Params.toArray());
|
||||
assertArrayEquals(new Double[]{0.4, 0.5, 0.6}, data.mDoubleParams.toArray());
|
||||
@@ -376,7 +376,7 @@ public class ProtoLogImplTest {
|
||||
ProtoLogData data = readProtoLogSingle(ip);
|
||||
assertNotNull(data);
|
||||
assertEquals(1234, data.mMessageHash.longValue());
|
||||
assertTrue(before < data.mElapsedTime && data.mElapsedTime < after);
|
||||
assertTrue(before <= data.mElapsedTime && data.mElapsedTime <= after);
|
||||
assertArrayEquals(new String[]{"test", "(INVALID PARAMS_MASK) true"},
|
||||
data.mStrParams.toArray());
|
||||
assertArrayEquals(new Long[]{1L}, data.mSint64Params.toArray());
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.github.javaparser.ast.CompilationUnit
|
||||
import com.github.javaparser.ast.ImportDeclaration
|
||||
import com.github.javaparser.ast.expr.BinaryExpr
|
||||
import com.github.javaparser.ast.expr.Expression
|
||||
import com.github.javaparser.ast.expr.MethodCallExpr
|
||||
import com.github.javaparser.ast.expr.StringLiteralExpr
|
||||
|
||||
object CodeUtils {
|
||||
@@ -27,8 +28,9 @@ object CodeUtils {
|
||||
* Returns a stable hash of a string.
|
||||
* We reimplement String::hashCode() for readability reasons.
|
||||
*/
|
||||
fun hash(str: String, level: LogLevel): Int {
|
||||
return (level.name + str).map { c -> c.toInt() }.reduce { h, c -> h * 31 + c }
|
||||
fun hash(position: String, messageString: String, logLevel: LogLevel, logGroup: LogGroup): Int {
|
||||
return (position + messageString + logLevel.name + logGroup.name)
|
||||
.map { c -> c.toInt() }.reduce { h, c -> h * 31 + c }
|
||||
}
|
||||
|
||||
fun isWildcardStaticImported(code: CompilationUnit, className: String): Boolean {
|
||||
@@ -71,4 +73,11 @@ object CodeUtils {
|
||||
"or concatenation of string literals.", expr)
|
||||
}
|
||||
}
|
||||
|
||||
fun getPositionString(call: MethodCallExpr, fileName: String): String {
|
||||
return when {
|
||||
call.range.isPresent -> "$fileName:${call.range.get().begin.line}"
|
||||
else -> fileName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ package com.android.protolog.tool
|
||||
object Constants {
|
||||
const val NAME = "protologtool"
|
||||
const val VERSION = "1.0.0"
|
||||
const val IS_LOG_TO_ANY_METHOD = "isLogToAny"
|
||||
const val IS_ENABLED_METHOD = "isEnabled"
|
||||
const val ENUM_VALUES_METHOD = "values"
|
||||
}
|
||||
|
||||
@@ -49,14 +49,14 @@ object ProtoLogTool {
|
||||
val file = File(path)
|
||||
val text = file.readText()
|
||||
val code = StaticJavaParser.parse(text)
|
||||
val outSrc = when {
|
||||
containsProtoLogText(text, command.protoLogClassNameArg) ->
|
||||
transformer.processClass(text, code)
|
||||
else -> text
|
||||
}
|
||||
val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
|
||||
.get().nameAsString else ""
|
||||
val newPath = pack.replace('.', '/') + '/' + file.name
|
||||
val outSrc = when {
|
||||
containsProtoLogText(text, command.protoLogClassNameArg) ->
|
||||
transformer.processClass(text, newPath, code)
|
||||
else -> text
|
||||
}
|
||||
outJar.putNextEntry(ZipEntry(newPath))
|
||||
outJar.write(outSrc.toByteArray())
|
||||
outJar.closeEntry()
|
||||
@@ -76,7 +76,11 @@ object ProtoLogTool {
|
||||
val file = File(path)
|
||||
val text = file.readText()
|
||||
if (containsProtoLogText(text, command.protoLogClassNameArg)) {
|
||||
builder.processClass(StaticJavaParser.parse(text))
|
||||
val code = StaticJavaParser.parse(text)
|
||||
val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
|
||||
.get().nameAsString else ""
|
||||
val newPath = pack.replace('.', '/') + '/' + file.name
|
||||
builder.processClass(code, newPath)
|
||||
}
|
||||
}
|
||||
val out = FileOutputStream(command.viewerConfigJsonArg)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.protolog.tool
|
||||
|
||||
import com.android.protolog.tool.Constants.IS_LOG_TO_ANY_METHOD
|
||||
import com.android.protolog.tool.Constants.IS_ENABLED_METHOD
|
||||
import com.android.server.protolog.common.LogDataType
|
||||
import com.github.javaparser.StaticJavaParser
|
||||
import com.github.javaparser.ast.CompilationUnit
|
||||
@@ -73,7 +73,8 @@ class SourceTransformer(
|
||||
}
|
||||
val ifStmt: IfStmt
|
||||
if (group.enabled) {
|
||||
val hash = CodeUtils.hash(messageString, level)
|
||||
val position = CodeUtils.getPositionString(call, fileName)
|
||||
val hash = CodeUtils.hash(position, messageString, level, group)
|
||||
val newCall = call.clone()
|
||||
if (!group.textEnabled) {
|
||||
// Remove message string if text logging is not enabled by default.
|
||||
@@ -90,12 +91,12 @@ class SourceTransformer(
|
||||
// Out: ProtoLog.e(GROUP, 1234, 0, null, arg)
|
||||
newCall.arguments.add(2, IntegerLiteralExpr(typeMask))
|
||||
// Replace call to a stub method with an actual implementation.
|
||||
// Out: com.android.server.wm.ProtoLogImpl.e(GROUP, 1234, null, arg)
|
||||
// Out: com.android.server.protolog.ProtoLogImpl.e(GROUP, 1234, null, arg)
|
||||
newCall.setScope(protoLogImplClassNode)
|
||||
// Create a call to GROUP.isLogAny()
|
||||
// Out: GROUP.isLogAny()
|
||||
val isLogAnyExpr = MethodCallExpr(newCall.arguments[0].clone(),
|
||||
SimpleName(IS_LOG_TO_ANY_METHOD))
|
||||
// Create a call to ProtoLogImpl.isEnabled(GROUP)
|
||||
// Out: com.android.server.protolog.ProtoLogImpl.isEnabled(GROUP)
|
||||
val isLogEnabled = MethodCallExpr(protoLogImplClassNode, IS_ENABLED_METHOD,
|
||||
NodeList<Expression>(newCall.arguments[0].clone()))
|
||||
if (argTypes.size != call.arguments.size - 2) {
|
||||
throw InvalidProtoLogCallException(
|
||||
"Number of arguments does not mach format string", call)
|
||||
@@ -120,11 +121,11 @@ class SourceTransformer(
|
||||
}
|
||||
blockStmt.addStatement(ExpressionStmt(newCall))
|
||||
// Create an IF-statement with the previously created condition.
|
||||
// Out: if (GROUP.isLogAny()) {
|
||||
// Out: if (com.android.server.protolog.ProtoLogImpl.isEnabled(GROUP)) {
|
||||
// long protoLogParam0 = arg;
|
||||
// com.android.server.wm.ProtoLogImpl.e(GROUP, 1234, 0, null, protoLogParam0);
|
||||
// com.android.server.protolog.ProtoLogImpl.e(GROUP, 1234, 0, null, protoLogParam0);
|
||||
// }
|
||||
ifStmt = IfStmt(isLogAnyExpr, blockStmt, null)
|
||||
ifStmt = IfStmt(isLogEnabled, blockStmt, null)
|
||||
} else {
|
||||
// Surround with if (false).
|
||||
val newCall = parentStmt.clone()
|
||||
@@ -212,12 +213,15 @@ class SourceTransformer(
|
||||
StaticJavaParser.parseExpression<FieldAccessExpr>(protoLogImplClassName)
|
||||
private var processedCode: MutableList<String> = mutableListOf()
|
||||
private var offsets: IntArray = IntArray(0)
|
||||
private var fileName: String = ""
|
||||
|
||||
fun processClass(
|
||||
code: String,
|
||||
path: String,
|
||||
compilationUnit: CompilationUnit =
|
||||
StaticJavaParser.parse(code)
|
||||
): String {
|
||||
fileName = path
|
||||
processedCode = code.split('\n').toMutableList()
|
||||
offsets = IntArray(processedCode.size)
|
||||
LexicalPreservingPrinter.setup(compilationUnit)
|
||||
|
||||
@@ -32,24 +32,28 @@ class ViewerConfigBuilder(
|
||||
group: LogGroup
|
||||
) {
|
||||
if (group.enabled) {
|
||||
val key = CodeUtils.hash(messageString, level)
|
||||
val position = CodeUtils.getPositionString(call, fileName)
|
||||
val key = CodeUtils.hash(position, messageString, level, group)
|
||||
if (statements.containsKey(key)) {
|
||||
if (statements[key] != Triple(messageString, level, group)) {
|
||||
if (statements[key] != LogCall(messageString, level, group, position)) {
|
||||
throw HashCollisionException(
|
||||
"Please modify the log message \"$messageString\" " +
|
||||
"or \"${statements[key]}\" - their hashes are equal.")
|
||||
}
|
||||
} else {
|
||||
groups.add(group)
|
||||
statements[key] = Triple(messageString, level, group)
|
||||
statements[key] = LogCall(messageString, level, group, position)
|
||||
call.range.isPresent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val statements: MutableMap<Int, Triple<String, LogLevel, LogGroup>> = mutableMapOf()
|
||||
private val statements: MutableMap<Int, LogCall> = mutableMapOf()
|
||||
private val groups: MutableSet<LogGroup> = mutableSetOf()
|
||||
private var fileName: String = ""
|
||||
|
||||
fun processClass(unit: CompilationUnit) {
|
||||
fun processClass(unit: CompilationUnit, fileName: String) {
|
||||
this.fileName = fileName
|
||||
protoLogCallVisitor.process(unit, this)
|
||||
}
|
||||
|
||||
@@ -66,11 +70,13 @@ class ViewerConfigBuilder(
|
||||
writer.name(key.toString())
|
||||
writer.beginObject()
|
||||
writer.name("message")
|
||||
writer.value(value.first)
|
||||
writer.value(value.messageString)
|
||||
writer.name("level")
|
||||
writer.value(value.second.name)
|
||||
writer.value(value.logLevel.name)
|
||||
writer.name("group")
|
||||
writer.value(value.third.name)
|
||||
writer.value(value.logGroup.name)
|
||||
writer.name("at")
|
||||
writer.value(value.position)
|
||||
writer.endObject()
|
||||
}
|
||||
writer.endObject()
|
||||
@@ -88,4 +94,11 @@ class ViewerConfigBuilder(
|
||||
stringWriter.buffer.append('\n')
|
||||
return stringWriter.toString()
|
||||
}
|
||||
|
||||
data class LogCall(
|
||||
val messageString: String,
|
||||
val logLevel: LogLevel,
|
||||
val logGroup: LogGroup,
|
||||
val position: String
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27,17 +27,32 @@ import org.junit.Test
|
||||
class CodeUtilsTest {
|
||||
@Test
|
||||
fun hash() {
|
||||
assertEquals(-1704685243, CodeUtils.hash("test", LogLevel.DEBUG))
|
||||
assertEquals(-1259556708, CodeUtils.hash("Test.java:50", "test",
|
||||
LogLevel.DEBUG, LogGroup("test", true, true, "TAG")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hash_changeLocation() {
|
||||
assertEquals(15793504, CodeUtils.hash("Test.java:10", "test2",
|
||||
LogLevel.DEBUG, LogGroup("test", true, true, "TAG")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hash_changeLevel() {
|
||||
assertEquals(-1176900998, CodeUtils.hash("test", LogLevel.ERROR))
|
||||
assertEquals(-731772463, CodeUtils.hash("Test.java:50", "test",
|
||||
LogLevel.ERROR, LogGroup("test", true, true, "TAG")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hash_changeMessage() {
|
||||
assertEquals(-1305634931, CodeUtils.hash("test2", LogLevel.DEBUG))
|
||||
assertEquals(-2026343204, CodeUtils.hash("Test.java:50", "test2",
|
||||
LogLevel.DEBUG, LogGroup("test", true, true, "TAG")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hash_changeGroup() {
|
||||
assertEquals(1607870166, CodeUtils.hash("Test.java:50", "test2",
|
||||
LogLevel.DEBUG, LogGroup("test2", true, true, "TAG")))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -78,7 +78,7 @@ class SourceTransformerTest {
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
if (TEST_GROUP.isLogToAny()) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 835524026, 9, "test %d %f", protoLogParam0, protoLogParam1); }
|
||||
if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 1922613844, 9, "test %d %f", protoLogParam0, protoLogParam1); }
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -88,7 +88,7 @@ class SourceTransformerTest {
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
if (TEST_GROUP.isLogToAny()) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -986393606, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2);
|
||||
if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, 805272208, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -100,8 +100,8 @@ class SourceTransformerTest {
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
if (TEST_GROUP.isLogToAny()) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 835524026, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (TEST_GROUP.isLogToAny()) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 835524026, 9, "test %d %f", protoLogParam0, protoLogParam1); }
|
||||
if (TEST_GROUP.isLogToAny()) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 835524026, 9, "test %d %f", protoLogParam0, protoLogParam1); }
|
||||
if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 1922613844, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 1922613844, 9, "test %d %f", protoLogParam0, protoLogParam1); }
|
||||
if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -154595499, 9, "test %d %f", protoLogParam0, protoLogParam1); }
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -111,7 +111,7 @@ class SourceTransformerTest {
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
if (TEST_GROUP.isLogToAny()) { org.example.ProtoLogImpl.w(TEST_GROUP, 1282022424, 0, "test", (Object[]) null); }
|
||||
if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { org.example.ProtoLogImpl.w(TEST_GROUP, 1913810354, 0, "test", (Object[]) null); }
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -121,7 +121,7 @@ class SourceTransformerTest {
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
if (TEST_GROUP.isLogToAny()) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 835524026, 9, null, protoLogParam0, protoLogParam1); }
|
||||
if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, 1922613844, 9, null, protoLogParam0, protoLogParam1); }
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@@ -131,7 +131,7 @@ class SourceTransformerTest {
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
if (TEST_GROUP.isLogToAny()) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -986393606, 9, null, protoLogParam0, protoLogParam1, protoLogParam2);
|
||||
if (org.example.ProtoLogImpl.isEnabled(TEST_GROUP)) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, 805272208, 9, null, protoLogParam0, protoLogParam1, protoLogParam2);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -160,10 +160,13 @@ class SourceTransformerTest {
|
||||
}
|
||||
""".trimIndent()
|
||||
/* ktlint-enable max-line-length */
|
||||
|
||||
private const val PATH = "com.example.Test.java"
|
||||
}
|
||||
|
||||
private val processor: ProtoLogCallProcessor = Mockito.mock(ProtoLogCallProcessor::class.java)
|
||||
private val sourceJarWriter = SourceTransformer("org.example.ProtoLogImpl", processor)
|
||||
private val implPath = "org.example.ProtoLogImpl"
|
||||
private val sourceJarWriter = SourceTransformer(implPath, processor)
|
||||
|
||||
private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
|
||||
|
||||
@@ -181,13 +184,13 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
assertEquals(1, ifStmts.size)
|
||||
val ifStmt = ifStmts[0]
|
||||
assertEquals("TEST_GROUP.${Constants.IS_LOG_TO_ANY_METHOD}()",
|
||||
assertEquals("$implPath.${Constants.IS_ENABLED_METHOD}(TEST_GROUP)",
|
||||
ifStmt.condition.toString())
|
||||
assertFalse(ifStmt.elseStmt.isPresent)
|
||||
assertEquals(3, ifStmt.thenStmt.childNodes.size)
|
||||
@@ -196,7 +199,7 @@ class SourceTransformerTest {
|
||||
assertEquals("w", methodCall.name.asString())
|
||||
assertEquals(6, methodCall.arguments.size)
|
||||
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
|
||||
assertEquals("835524026", methodCall.arguments[1].toString())
|
||||
assertEquals("1922613844", methodCall.arguments[1].toString())
|
||||
assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
|
||||
assertEquals("\"test %d %f\"", methodCall.arguments[3].toString())
|
||||
assertEquals("protoLogParam0", methodCall.arguments[4].toString())
|
||||
@@ -223,13 +226,13 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTICALLS, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTICALLS, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
assertEquals(3, ifStmts.size)
|
||||
val ifStmt = ifStmts[1]
|
||||
assertEquals("TEST_GROUP.${Constants.IS_LOG_TO_ANY_METHOD}()",
|
||||
assertEquals("$implPath.${Constants.IS_ENABLED_METHOD}(TEST_GROUP)",
|
||||
ifStmt.condition.toString())
|
||||
assertFalse(ifStmt.elseStmt.isPresent)
|
||||
assertEquals(3, ifStmt.thenStmt.childNodes.size)
|
||||
@@ -238,7 +241,7 @@ class SourceTransformerTest {
|
||||
assertEquals("w", methodCall.name.asString())
|
||||
assertEquals(6, methodCall.arguments.size)
|
||||
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
|
||||
assertEquals("835524026", methodCall.arguments[1].toString())
|
||||
assertEquals("1922613844", methodCall.arguments[1].toString())
|
||||
assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
|
||||
assertEquals("\"test %d %f\"", methodCall.arguments[3].toString())
|
||||
assertEquals("protoLogParam0", methodCall.arguments[4].toString())
|
||||
@@ -261,13 +264,13 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
assertEquals(1, ifStmts.size)
|
||||
val ifStmt = ifStmts[0]
|
||||
assertEquals("TEST_GROUP.${Constants.IS_LOG_TO_ANY_METHOD}()",
|
||||
assertEquals("$implPath.${Constants.IS_ENABLED_METHOD}(TEST_GROUP)",
|
||||
ifStmt.condition.toString())
|
||||
assertFalse(ifStmt.elseStmt.isPresent)
|
||||
assertEquals(4, ifStmt.thenStmt.childNodes.size)
|
||||
@@ -276,7 +279,7 @@ class SourceTransformerTest {
|
||||
assertEquals("w", methodCall.name.asString())
|
||||
assertEquals(7, methodCall.arguments.size)
|
||||
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
|
||||
assertEquals("-986393606", methodCall.arguments[1].toString())
|
||||
assertEquals("805272208", methodCall.arguments[1].toString())
|
||||
assertEquals(0b001001.toString(), methodCall.arguments[2].toString())
|
||||
assertEquals("protoLogParam0", methodCall.arguments[4].toString())
|
||||
assertEquals("protoLogParam1", methodCall.arguments[5].toString())
|
||||
@@ -298,13 +301,13 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_NO_PARAMS, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_NO_PARAMS, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
assertEquals(1, ifStmts.size)
|
||||
val ifStmt = ifStmts[0]
|
||||
assertEquals("TEST_GROUP.${Constants.IS_LOG_TO_ANY_METHOD}()",
|
||||
assertEquals("$implPath.${Constants.IS_ENABLED_METHOD}(TEST_GROUP)",
|
||||
ifStmt.condition.toString())
|
||||
assertFalse(ifStmt.elseStmt.isPresent)
|
||||
assertEquals(1, ifStmt.thenStmt.childNodes.size)
|
||||
@@ -313,7 +316,7 @@ class SourceTransformerTest {
|
||||
assertEquals("w", methodCall.name.asString())
|
||||
assertEquals(5, methodCall.arguments.size)
|
||||
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
|
||||
assertEquals("1282022424", methodCall.arguments[1].toString())
|
||||
assertEquals("1913810354", methodCall.arguments[1].toString())
|
||||
assertEquals(0.toString(), methodCall.arguments[2].toString())
|
||||
assertEquals(TRANSFORMED_CODE_NO_PARAMS, out)
|
||||
}
|
||||
@@ -332,13 +335,13 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
assertEquals(1, ifStmts.size)
|
||||
val ifStmt = ifStmts[0]
|
||||
assertEquals("TEST_GROUP.${Constants.IS_LOG_TO_ANY_METHOD}()",
|
||||
assertEquals("$implPath.${Constants.IS_ENABLED_METHOD}(TEST_GROUP)",
|
||||
ifStmt.condition.toString())
|
||||
assertFalse(ifStmt.elseStmt.isPresent)
|
||||
assertEquals(3, ifStmt.thenStmt.childNodes.size)
|
||||
@@ -347,7 +350,7 @@ class SourceTransformerTest {
|
||||
assertEquals("w", methodCall.name.asString())
|
||||
assertEquals(6, methodCall.arguments.size)
|
||||
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
|
||||
assertEquals("835524026", methodCall.arguments[1].toString())
|
||||
assertEquals("1922613844", methodCall.arguments[1].toString())
|
||||
assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
|
||||
assertEquals("null", methodCall.arguments[3].toString())
|
||||
assertEquals("protoLogParam0", methodCall.arguments[4].toString())
|
||||
@@ -370,13 +373,13 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
assertEquals(1, ifStmts.size)
|
||||
val ifStmt = ifStmts[0]
|
||||
assertEquals("TEST_GROUP.${Constants.IS_LOG_TO_ANY_METHOD}()",
|
||||
assertEquals("$implPath.${Constants.IS_ENABLED_METHOD}(TEST_GROUP)",
|
||||
ifStmt.condition.toString())
|
||||
assertFalse(ifStmt.elseStmt.isPresent)
|
||||
assertEquals(4, ifStmt.thenStmt.childNodes.size)
|
||||
@@ -385,7 +388,7 @@ class SourceTransformerTest {
|
||||
assertEquals("w", methodCall.name.asString())
|
||||
assertEquals(7, methodCall.arguments.size)
|
||||
assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
|
||||
assertEquals("-986393606", methodCall.arguments[1].toString())
|
||||
assertEquals("805272208", methodCall.arguments[1].toString())
|
||||
assertEquals(0b001001.toString(), methodCall.arguments[2].toString())
|
||||
assertEquals("null", methodCall.arguments[3].toString())
|
||||
assertEquals("protoLogParam0", methodCall.arguments[4].toString())
|
||||
@@ -408,7 +411,7 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
@@ -433,7 +436,7 @@ class SourceTransformerTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, code)
|
||||
val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, code)
|
||||
code = StaticJavaParser.parse(out)
|
||||
|
||||
val ifStmts = code.findAll(IfStmt::class.java)
|
||||
|
||||
@@ -31,6 +31,10 @@ class ViewerConfigBuilderTest {
|
||||
private val TEST1 = ViewerConfigParser.ConfigEntry("test1", LogLevel.INFO.name, TAG1)
|
||||
private val TEST2 = ViewerConfigParser.ConfigEntry("test2", LogLevel.DEBUG.name, TAG2)
|
||||
private val TEST3 = ViewerConfigParser.ConfigEntry("test3", LogLevel.ERROR.name, TAG2)
|
||||
private val GROUP1 = LogGroup("TEST_GROUP", true, true, TAG1)
|
||||
private val GROUP2 = LogGroup("DEBUG_GROUP", true, true, TAG2)
|
||||
private val GROUP3 = LogGroup("DEBUG_GROUP", true, true, TAG2)
|
||||
private const val PATH = "/tmp/test.java"
|
||||
}
|
||||
|
||||
private val processor: ProtoLogCallProcessor = Mockito.mock(ProtoLogCallProcessor::class.java)
|
||||
@@ -50,25 +54,25 @@ class ViewerConfigBuilderTest {
|
||||
val visitor = invocation.arguments[1] as ProtoLogCallVisitor
|
||||
|
||||
visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
|
||||
LogGroup("TEST_GROUP", true, true, TAG1))
|
||||
GROUP1)
|
||||
visitor.processCall(MethodCallExpr(), TEST2.messageString, LogLevel.DEBUG,
|
||||
LogGroup("DEBUG_GROUP", true, true, TAG2))
|
||||
GROUP2)
|
||||
visitor.processCall(MethodCallExpr(), TEST3.messageString, LogLevel.ERROR,
|
||||
LogGroup("DEBUG_GROUP", true, true, TAG2))
|
||||
GROUP3)
|
||||
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
configBuilder.processClass(dummyCompilationUnit)
|
||||
configBuilder.processClass(dummyCompilationUnit, PATH)
|
||||
|
||||
val parsedConfig = parseConfig(configBuilder.build())
|
||||
assertEquals(3, parsedConfig.size)
|
||||
assertEquals(TEST1, parsedConfig[CodeUtils.hash(TEST1.messageString,
|
||||
LogLevel.INFO)])
|
||||
assertEquals(TEST2, parsedConfig[CodeUtils.hash(TEST2.messageString,
|
||||
LogLevel.DEBUG)])
|
||||
assertEquals(TEST3, parsedConfig[CodeUtils.hash(TEST3.messageString,
|
||||
LogLevel.ERROR)])
|
||||
assertEquals(TEST1, parsedConfig[CodeUtils.hash(PATH,
|
||||
TEST1.messageString, LogLevel.INFO, GROUP1)])
|
||||
assertEquals(TEST2, parsedConfig[CodeUtils.hash(PATH, TEST2.messageString,
|
||||
LogLevel.DEBUG, GROUP2)])
|
||||
assertEquals(TEST3, parsedConfig[CodeUtils.hash(PATH, TEST3.messageString,
|
||||
LogLevel.ERROR, GROUP3)])
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,20 +82,21 @@ class ViewerConfigBuilderTest {
|
||||
val visitor = invocation.arguments[1] as ProtoLogCallVisitor
|
||||
|
||||
visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
|
||||
LogGroup("TEST_GROUP", true, true, TAG1))
|
||||
GROUP1)
|
||||
visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
|
||||
LogGroup("TEST_GROUP", true, true, TAG1))
|
||||
GROUP1)
|
||||
visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
|
||||
LogGroup("TEST_GROUP", true, true, TAG1))
|
||||
GROUP1)
|
||||
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
configBuilder.processClass(dummyCompilationUnit)
|
||||
configBuilder.processClass(dummyCompilationUnit, PATH)
|
||||
|
||||
val parsedConfig = parseConfig(configBuilder.build())
|
||||
assertEquals(1, parsedConfig.size)
|
||||
assertEquals(TEST1, parsedConfig[CodeUtils.hash(TEST1.messageString, LogLevel.INFO)])
|
||||
assertEquals(TEST1, parsedConfig[CodeUtils.hash(PATH, TEST1.messageString,
|
||||
LogLevel.INFO, GROUP1)])
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -101,7 +106,7 @@ class ViewerConfigBuilderTest {
|
||||
val visitor = invocation.arguments[1] as ProtoLogCallVisitor
|
||||
|
||||
visitor.processCall(MethodCallExpr(), TEST1.messageString, LogLevel.INFO,
|
||||
LogGroup("TEST_GROUP", true, true, TAG1))
|
||||
GROUP1)
|
||||
visitor.processCall(MethodCallExpr(), TEST2.messageString, LogLevel.DEBUG,
|
||||
LogGroup("DEBUG_GROUP", false, true, TAG2))
|
||||
visitor.processCall(MethodCallExpr(), TEST3.messageString, LogLevel.ERROR,
|
||||
@@ -110,11 +115,13 @@ class ViewerConfigBuilderTest {
|
||||
invocation.arguments[0] as CompilationUnit
|
||||
}
|
||||
|
||||
configBuilder.processClass(dummyCompilationUnit)
|
||||
configBuilder.processClass(dummyCompilationUnit, PATH)
|
||||
|
||||
val parsedConfig = parseConfig(configBuilder.build())
|
||||
assertEquals(2, parsedConfig.size)
|
||||
assertEquals(TEST1, parsedConfig[CodeUtils.hash(TEST1.messageString, LogLevel.INFO)])
|
||||
assertEquals(TEST3, parsedConfig[CodeUtils.hash(TEST3.messageString, LogLevel.ERROR)])
|
||||
assertEquals(TEST1, parsedConfig[CodeUtils.hash(PATH, TEST1.messageString,
|
||||
LogLevel.INFO, GROUP1)])
|
||||
assertEquals(TEST3, parsedConfig[CodeUtils.hash(PATH, TEST3.messageString,
|
||||
LogLevel.ERROR, LogGroup("DEBUG_GROUP", true, false, TAG2))])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user