AndroidLogcatReceiver extends AndroidOutputReceiver implements Disposable { @Override public void processNewLine(@NotNull String line) { line = CARRIAGE_RETURN.matcher(line).replaceAll(""); if (line.isEmpty()) { myDelayedNewlineCount++; return; } LogCatHeader header = myLongEpochParser.processLogHeader(line, myDevice); if (header == null) { header = myLongParser.processLogHeader(line, myDevice); } if (header != null) { myStackTraceExpander.reset(); myActiveHeader = header; myLineIndex = 0; myDelayedNewlineCount = 0; } else if (myActiveHeader != null) { if (myDelayedNewlineCount > 0 && myLineIndex == 0) { myDelayedNewlineCount = 0; } else { processAnyDelayedNewlines(myActiveHeader); } for (String processedLine : myStackTraceExpander.process(line)) { notifyLine(myActiveHeader, processedLine); } } } AndroidLogcatReceiver(@NotNull IDevice device, @NotNull LogcatListener listener); @Override void processNewLine(@NotNull String line); @Override boolean isCancelled(); @Override void dispose(); void cancel();  }
@Test public void processNewLineWorksOnSimpleLogEntry() { myReceiver.processNewLine("[ 1534635551.439 1493:1595 W/EDMNativeHelper ]"); assertThat("").isEqualTo(myLogcatListener.toString()); myReceiver.processNewLine("EDMNativeHelperService is published"); String expected = "2018-08-18 16:39:11.439 1493-1595/dummy.client.name W/EDMNativeHelper: EDMNativeHelperService is published\n"; assertThat(myLogcatListener.toString()).isEqualTo(expected); }
@Test public void processNewLineUsesQuestionMarkForUnknownClientIds() { myReceiver.processNewLine("[ 1516739696.789 99:99 V/UnknownClient ]"); myReceiver.processNewLine("Dummy Message"); String expected = "2018-01-23 12:34:56.789 99-99/? V/UnknownClient: Dummy Message\n"; assertThat(myLogcatListener.toString()).isEqualTo(expected); }
@Test public void processNewLineHandlesMultilineLogs() { myReceiver.processNewLine("[ 1516739696.789 99:99 V/UnknownClient ]"); myReceiver.processNewLine("Line 1"); myReceiver.processNewLine("Line 2"); myReceiver.processNewLine("Line 3"); myReceiver.processNewLine(""); myReceiver.processNewLine("[ 1516741200.000 99:99 V/UnknownClient ]"); myReceiver.processNewLine("Line 1"); String expected = "2018-01-23 12:34:56.789 99-99/? V/UnknownClient: Line 1\n" + "+ Line 2\n" + "+ Line 3\n" + "2018-01-23 13:00:00.000 99-99/? V/UnknownClient: Line 1\n"; assertThat(myLogcatListener.toString()).isEqualTo(expected); }
@Test public void processNewLineHandlesUserNewlines() { myReceiver.processNewLine("[ 1516739696.789 99:99 V/UnknownClient ]"); myReceiver.processNewLine("1: {"); myReceiver.processNewLine("}"); myReceiver.processNewLine(""); myReceiver.processNewLine("[ 1516739696.790 99:99 V/UnknownClient ]"); myReceiver.processNewLine("2: {"); myReceiver.processNewLine(""); myReceiver.processNewLine("}"); myReceiver.processNewLine(""); myReceiver.processNewLine("[ 1516739696.791 99:99 V/UnknownClient ]"); myReceiver.processNewLine("3: {"); myReceiver.processNewLine(""); myReceiver.processNewLine(""); myReceiver.processNewLine("}"); myReceiver.processNewLine(""); myReceiver.processNewLine("[ 1516739696.792 99:99 V/UnknownClient ]"); myReceiver.processNewLine(""); myReceiver.processNewLine(""); myReceiver.processNewLine("leading-trimmed"); myReceiver.processNewLine(""); myReceiver.processNewLine("[ 1516739696.793 99:99 V/UnknownClient ]"); myReceiver.processNewLine("trailing-trimmed: {"); myReceiver.processNewLine(""); myReceiver.processNewLine(""); myReceiver.processNewLine(""); myReceiver.processNewLine("[ 1516739696.794 99:99 V/UnknownClient ]"); myReceiver.processNewLine("spaces: { "); myReceiver.processNewLine(" "); myReceiver.processNewLine(" "); myReceiver.processNewLine(" }"); myReceiver.processNewLine(""); myReceiver.processNewLine("[ 1516739696.795 99:99 V/UnknownClient ]"); myReceiver.processNewLine("normal log entry"); String expected = "2018-01-23 12:34:56.789 99-99/? V/UnknownClient: 1: {\n" + "+ }\n" + "2018-01-23 12:34:56.790 99-99/? V/UnknownClient: 2: {\n" + "+ \n" + "+ }\n" + "2018-01-23 12:34:56.791 99-99/? V/UnknownClient: 3: {\n" + "+ \n" + "+ \n" + "+ }\n" + "2018-01-23 12:34:56.792 99-99/? V/UnknownClient: leading-trimmed\n" + "2018-01-23 12:34:56.793 99-99/? V/UnknownClient: trailing-trimmed: {\n" + "2018-01-23 12:34:56.794 99-99/? V/UnknownClient: spaces: { \n" + "+ \n" + "+ \n" + "+ }\n" + "2018-01-23 12:34:56.795 99-99/? V/UnknownClient: normal log entry\n"; assertThat(myLogcatListener.toString()).isEqualTo(expected); }
@Test public void processNewLineHandlesException() { myReceiver.processNewLine("[ 1534643988.771 11698:11811 E/AndroidRuntime ]"); myReceiver.processNewLine("FATAL EXCEPTION: Timer-0"); myReceiver.processNewLine("Process: com.android.chattylogger, PID: 11698"); myReceiver.processNewLine("java.lang.RuntimeException: Bad response"); myReceiver.processNewLine(" at com.android.chattylogger.MainActivity$1.run(MainActivity.java:64)"); myReceiver.processNewLine(" at java.util.Timer$TimerImpl.run(Timer.java:284)"); String expected = "2018-08-18 18:59:48.771 11698-11811/com.android.chattylogger E/AndroidRuntime: FATAL EXCEPTION: Timer-0\n" + "+ Process: com.android.chattylogger, PID: 11698\n" + "+ java.lang.RuntimeException: Bad response\n" + "+ at com.android.chattylogger.MainActivity$1.run(MainActivity.java:64)\n" + "+ at java.util.Timer$TimerImpl.run(Timer.java:284)\n"; assertThat(myLogcatListener.toString()).isEqualTo(expected); }
@Test public void testParseAllLogLevelsAndHexThreadIds() { String[] messages = new String[]{ "[ 1534039867.132 495:0x1ef D/dtag ]", "debug message", "[ 1534039867.132 495: 234 E/etag ]", "error message", "[ 1534039867.132 495:0x1ef I/itag ]", "info message", "[ 1534039867.132 495:0x1ef V/vtag ]", "verbose message", "[ 1534039867.132 495:0x1ef W/wtag ]", "warning message", "[ 1534039867.132 495:0x1ef F/wtftag ]", "wtf message", "[ 1534047335.754 540:0x21c D/debug tag ]", "debug message", "[ 1534047335.754 540:0x21c I/tag:with:colons ]", "message:with:colons", }; for (String message : messages) { myReceiver.processNewLine(message); } String expected = "2018-08-11 19:11:07.132 495-495/? D/dtag: debug message\n" + "2018-08-11 19:11:07.132 495-234/? E/etag: error message\n" + "2018-08-11 19:11:07.132 495-495/? I/itag: info message\n" + "2018-08-11 19:11:07.132 495-495/? V/vtag: verbose message\n" + "2018-08-11 19:11:07.132 495-495/? W/wtag: warning message\n" + "2018-08-11 19:11:07.132 495-495/? A/wtftag: wtf message\n" + "2018-08-11 21:15:35.754 540-540/? D/debug tag: debug message\n" + "2018-08-11 21:15:35.754 540-540/? I/tag:with:colons: message:with:colons\n"; assertThat(myLogcatListener.toString()).isEqualTo(expected); }