[android] Change the recommended log tag format to "cr_foo"
This is to ensure that log tags are not elided when retrieving logcat output from crash reports. The log function has been modified to make the transition easier and avoid specifying the prefix everywhere. This patch also moves some eliding testing from instrumentation tests to junit tests, and adds a test to ensure that the new tag format is not elided. BUG=533072 Review URL: https://codereview.chromium.org/1354723004 Cr-Commit-Position: refs/heads/master@{#349733}
This commit is contained in:
PRESUBMIT.pyPRESUBMIT_test.py
base/android
chrome/android
javatests
src
org
chromium
chrome
browser
junit
src
org
chromium
chrome
browser
docs
25
PRESUBMIT.py
25
PRESUBMIT.py
@ -1353,8 +1353,7 @@ def _CheckAndroidToastUsage(input_api, output_api):
|
||||
def _CheckAndroidCrLogUsage(input_api, output_api):
|
||||
"""Checks that new logs using org.chromium.base.Log:
|
||||
- Are using 'TAG' as variable name for the tags (warn)
|
||||
- Are using the suggested name format for the tags: "cr.<PackageTag>" (warn)
|
||||
- Are using a tag that is shorter than 23 characters (error)
|
||||
- Are using a tag that is shorter than 20 characters (error)
|
||||
"""
|
||||
cr_log_import_pattern = input_api.re.compile(
|
||||
r'^import org\.chromium\.base\.Log;$', input_api.re.MULTILINE)
|
||||
@ -1365,9 +1364,8 @@ def _CheckAndroidCrLogUsage(input_api, output_api):
|
||||
# Extract the tag from lines like `Log.d(TAG, "*");` or `Log.d("TAG", "*");`
|
||||
log_call_pattern = input_api.re.compile(r'^\s*Log\.\w\((?P<tag>\"?\w+\"?)\,')
|
||||
log_decl_pattern = input_api.re.compile(
|
||||
r'^\s*private static final String TAG = "(?P<name>(.*)")',
|
||||
r'^\s*private static final String TAG = "(?P<name>(.*))";',
|
||||
input_api.re.MULTILINE)
|
||||
log_name_pattern = input_api.re.compile(r'^cr[.\w]*')
|
||||
|
||||
REF_MSG = ('See docs/android_logging.md '
|
||||
'or contact dgn@chromium.org for more info.')
|
||||
@ -1376,6 +1374,7 @@ def _CheckAndroidCrLogUsage(input_api, output_api):
|
||||
tag_decl_errors = []
|
||||
tag_length_errors = []
|
||||
tag_errors = []
|
||||
tag_with_dot_errors = []
|
||||
util_log_errors = []
|
||||
|
||||
for f in input_api.AffectedSourceFiles(sources):
|
||||
@ -1407,23 +1406,26 @@ def _CheckAndroidCrLogUsage(input_api, output_api):
|
||||
if has_modified_logs:
|
||||
# Make sure the tag is using the "cr" prefix and is not too long
|
||||
match = log_decl_pattern.search(file_content)
|
||||
tag_name = match.group('name') if match else ''
|
||||
if not log_name_pattern.search(tag_name ):
|
||||
tag_name = match.group('name') if match else None
|
||||
if not tag_name:
|
||||
tag_decl_errors.append(f.LocalPath())
|
||||
if len(tag_name) > 23:
|
||||
elif len(tag_name) > 20:
|
||||
tag_length_errors.append(f.LocalPath())
|
||||
elif '.' in tag_name:
|
||||
tag_with_dot_errors.append(f.LocalPath())
|
||||
|
||||
results = []
|
||||
if tag_decl_errors:
|
||||
results.append(output_api.PresubmitPromptWarning(
|
||||
'Please define your tags using the suggested format: .\n'
|
||||
'"private static final String TAG = "cr.<package tag>".\n' + REF_MSG,
|
||||
'"private static final String TAG = "<package tag>".\n'
|
||||
'They will be prepended with "cr_" automatically.\n' + REF_MSG,
|
||||
tag_decl_errors))
|
||||
|
||||
if tag_length_errors:
|
||||
results.append(output_api.PresubmitError(
|
||||
'The tag length is restricted by the system to be at most '
|
||||
'23 characters.\n' + REF_MSG,
|
||||
'20 characters.\n' + REF_MSG,
|
||||
tag_length_errors))
|
||||
|
||||
if tag_errors:
|
||||
@ -1436,6 +1438,11 @@ def _CheckAndroidCrLogUsage(input_api, output_api):
|
||||
'Please use org.chromium.base.Log for new logs.\n' + REF_MSG,
|
||||
util_log_errors))
|
||||
|
||||
if tag_with_dot_errors:
|
||||
results.append(output_api.PresubmitPromptWarning(
|
||||
'Dot in log tags cause them to be elided in crash reports.\n' + REF_MSG,
|
||||
tag_with_dot_errors))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
|
@ -463,7 +463,7 @@ class CheckAddedDepsHaveTetsApprovalsTest(unittest.TestCase):
|
||||
'"+chrome/plugin/chrome_content_plugin_client.h",',
|
||||
'"+chrome/utility/chrome_content_utility_client.h",',
|
||||
'"+chromeos/chromeos_paths.h",',
|
||||
'"+components/crash",',
|
||||
'"+components/crash/content",',
|
||||
'"+components/nacl/common",',
|
||||
'"+content/public/browser/render_process_host.h",',
|
||||
'"+jni/fooblat.h",',
|
||||
@ -840,32 +840,38 @@ class LogUsageTest(unittest.TestCase):
|
||||
]),
|
||||
MockAffectedFile('IsInBasePackage.java', [
|
||||
'package org.chromium.base;',
|
||||
'private static final String TAG = "cr.Foo";',
|
||||
'private static final String TAG = "cr_Foo";',
|
||||
'Log.d(TAG, "foo");',
|
||||
]),
|
||||
MockAffectedFile('IsInBasePackageButImportsLog.java', [
|
||||
'package org.chromium.base;',
|
||||
'import android.util.Log;',
|
||||
'private static final String TAG = "cr.Foo";',
|
||||
'private static final String TAG = "cr_Foo";',
|
||||
'Log.d(TAG, "foo");',
|
||||
]),
|
||||
MockAffectedFile('HasBothLog.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'some random stuff',
|
||||
'private static final String TAG = "cr.Foo";',
|
||||
'private static final String TAG = "cr_Foo";',
|
||||
'Log.d(TAG, "foo");',
|
||||
'android.util.Log.d("TAG", "foo");',
|
||||
]),
|
||||
MockAffectedFile('HasCorrectTag.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'some random stuff',
|
||||
'private static final String TAG = "cr_Foo";',
|
||||
'Log.d(TAG, "foo");',
|
||||
]),
|
||||
MockAffectedFile('HasOldTag.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'some random stuff',
|
||||
'private static final String TAG = "cr.Foo";',
|
||||
'Log.d(TAG, "foo");',
|
||||
]),
|
||||
MockAffectedFile('HasShortCorrectTag.java', [
|
||||
MockAffectedFile('HasDottedTag.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'some random stuff',
|
||||
'private static final String TAG = "cr";',
|
||||
'private static final String TAG = "cr_foo.bar";',
|
||||
'Log.d(TAG, "foo");',
|
||||
]),
|
||||
MockAffectedFile('HasNoTagDecl.java', [
|
||||
@ -875,17 +881,17 @@ class LogUsageTest(unittest.TestCase):
|
||||
]),
|
||||
MockAffectedFile('HasIncorrectTagDecl.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'private static final String TAHG = "cr.Foo";',
|
||||
'private static final String TAHG = "cr_Foo";',
|
||||
'some random stuff',
|
||||
'Log.d(TAG, "foo");',
|
||||
]),
|
||||
MockAffectedFile('HasInlineTag.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'some random stuff',
|
||||
'private static final String TAG = "cr.Foo";',
|
||||
'private static final String TAG = "cr_Foo";',
|
||||
'Log.d("TAG", "foo");',
|
||||
]),
|
||||
MockAffectedFile('HasIncorrectTag.java', [
|
||||
MockAffectedFile('HasUnprefixedTag.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'some random stuff',
|
||||
'private static final String TAG = "rubbish";',
|
||||
@ -894,7 +900,7 @@ class LogUsageTest(unittest.TestCase):
|
||||
MockAffectedFile('HasTooLongTag.java', [
|
||||
'import org.chromium.base.Log;',
|
||||
'some random stuff',
|
||||
'private static final String TAG = "cr.24_charachers_long___";',
|
||||
'private static final String TAG = "21_charachers_long___";',
|
||||
'Log.d(TAG, "foo");',
|
||||
]),
|
||||
]
|
||||
@ -902,27 +908,42 @@ class LogUsageTest(unittest.TestCase):
|
||||
msgs = PRESUBMIT._CheckAndroidCrLogUsage(
|
||||
mock_input_api, mock_output_api)
|
||||
|
||||
self.assertEqual(4, len(msgs))
|
||||
self.assertEqual(5, len(msgs),
|
||||
'Expected %d items, found %d: %s' % (5, len(msgs), msgs))
|
||||
|
||||
# Declaration format
|
||||
self.assertEqual(3, len(msgs[0].items))
|
||||
nb = len(msgs[0].items)
|
||||
self.assertEqual(2, nb,
|
||||
'Expected %d items, found %d: %s' % (2, nb, msgs[0].items))
|
||||
self.assertTrue('HasNoTagDecl.java' in msgs[0].items)
|
||||
self.assertTrue('HasIncorrectTagDecl.java' in msgs[0].items)
|
||||
self.assertTrue('HasIncorrectTag.java' in msgs[0].items)
|
||||
|
||||
# Tag length
|
||||
self.assertEqual(1, len(msgs[1].items))
|
||||
nb = len(msgs[1].items)
|
||||
self.assertEqual(1, nb,
|
||||
'Expected %d items, found %d: %s' % (1, nb, msgs[1].items))
|
||||
self.assertTrue('HasTooLongTag.java' in msgs[1].items)
|
||||
|
||||
# Tag must be a variable named TAG
|
||||
self.assertEqual(1, len(msgs[2].items))
|
||||
nb = len(msgs[2].items)
|
||||
self.assertEqual(1, nb,
|
||||
'Expected %d items, found %d: %s' % (1, nb, msgs[2].items))
|
||||
self.assertTrue('HasInlineTag.java:4' in msgs[2].items)
|
||||
|
||||
# Util Log usage
|
||||
self.assertEqual(2, len(msgs[3].items))
|
||||
nb = len(msgs[3].items)
|
||||
self.assertEqual(2, nb,
|
||||
'Expected %d items, found %d: %s' % (2, nb, msgs[3].items))
|
||||
self.assertTrue('HasAndroidLog.java:3' in msgs[3].items)
|
||||
self.assertTrue('IsInBasePackageButImportsLog.java:4' in msgs[3].items)
|
||||
|
||||
# Tag must not contain
|
||||
nb = len(msgs[4].items)
|
||||
self.assertEqual(2, nb,
|
||||
'Expected %d items, found %d: %s' % (2, nb, msgs[4].items))
|
||||
self.assertTrue('HasDottedTag.java' in msgs[4].items)
|
||||
self.assertTrue('HasOldTag.java' in msgs[4].items)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -39,6 +39,9 @@ public class Log {
|
||||
/** Convenience property, same as {@link android.util.Log#WARN}. */
|
||||
public static final int WARN = android.util.Log.WARN;
|
||||
|
||||
private static final String sTagPrefix = "cr_";
|
||||
private static final String sDeprecatedTagPrefix = "cr.";
|
||||
|
||||
private Log() {
|
||||
// Static only access
|
||||
}
|
||||
@ -52,6 +55,24 @@ public class Log {
|
||||
return messageTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a normalized tag that will be in the form: "cr_foo". This function is called by the
|
||||
* various Log overrides. If using {@link #isLoggable(String, int)}, you might want to call it
|
||||
* to get the tag that will actually be used.
|
||||
* @see #sTagPrefix
|
||||
*/
|
||||
public static String normalizeTag(String tag) {
|
||||
if (tag.startsWith(sTagPrefix)) return tag;
|
||||
|
||||
// TODO(dgn) simplify this once 'cr.' is out of the repo (http://crbug.com/533072)
|
||||
int unprefixedTagStart = 0;
|
||||
if (tag.startsWith(sDeprecatedTagPrefix)) {
|
||||
unprefixedTagStart = sDeprecatedTagPrefix.length();
|
||||
}
|
||||
|
||||
return sTagPrefix + tag.substring(unprefixedTagStart, tag.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted log message, using the supplied format and arguments.
|
||||
* The message will be prepended with the filename and line number of the call.
|
||||
@ -77,7 +98,8 @@ public class Log {
|
||||
* than 7 parameters, consider building your log message using a function annotated with
|
||||
* {@link RemovableInRelease}.
|
||||
*
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tag Used to identify the source of a log message. Might be modified in the output
|
||||
* (see {@link #normalizeTag(String)})
|
||||
* @param messageTemplate The message you would like logged. It is to be specified as a format
|
||||
* string.
|
||||
* @param args Arguments referenced by the format specifiers in the format string. If the last
|
||||
@ -87,9 +109,9 @@ public class Log {
|
||||
String message = formatLogWithStack(messageTemplate, args);
|
||||
Throwable tr = getThrowableToLog(args);
|
||||
if (tr != null) {
|
||||
android.util.Log.v(tag, message, tr);
|
||||
android.util.Log.v(normalizeTag(tag), message, tr);
|
||||
} else {
|
||||
android.util.Log.v(tag, message);
|
||||
android.util.Log.v(normalizeTag(tag), message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,7 +183,8 @@ public class Log {
|
||||
* than 7 parameters, consider building your log message using a function annotated with
|
||||
* {@link RemovableInRelease}.
|
||||
*
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tag Used to identify the source of a log message. Might be modified in the output
|
||||
* (see {@link #normalizeTag(String)})
|
||||
* @param messageTemplate The message you would like logged. It is to be specified as a format
|
||||
* string.
|
||||
* @param args Arguments referenced by the format specifiers in the format string. If the last
|
||||
@ -171,9 +194,9 @@ public class Log {
|
||||
String message = formatLogWithStack(messageTemplate, args);
|
||||
Throwable tr = getThrowableToLog(args);
|
||||
if (tr != null) {
|
||||
android.util.Log.d(tag, message, tr);
|
||||
android.util.Log.d(normalizeTag(tag), message, tr);
|
||||
} else {
|
||||
android.util.Log.d(tag, message);
|
||||
android.util.Log.d(normalizeTag(tag), message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +262,8 @@ public class Log {
|
||||
/**
|
||||
* Sends an {@link android.util.Log#INFO} log message.
|
||||
*
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tag Used to identify the source of a log message. Might be modified in the output
|
||||
* (see {@link #normalizeTag(String)})
|
||||
* @param messageTemplate The message you would like logged. It is to be specified as a format
|
||||
* string.
|
||||
* @param args Arguments referenced by the format specifiers in the format string. If the last
|
||||
@ -250,16 +274,17 @@ public class Log {
|
||||
String message = formatLog(messageTemplate, args);
|
||||
Throwable tr = getThrowableToLog(args);
|
||||
if (tr != null) {
|
||||
android.util.Log.i(tag, message, tr);
|
||||
android.util.Log.i(normalizeTag(tag), message, tr);
|
||||
} else {
|
||||
android.util.Log.i(tag, message);
|
||||
android.util.Log.i(normalizeTag(tag), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a {@link android.util.Log#WARN} log message.
|
||||
*
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tag Used to identify the source of a log message. Might be modified in the output
|
||||
* (see {@link #normalizeTag(String)})
|
||||
* @param messageTemplate The message you would like logged. It is to be specified as a format
|
||||
* string.
|
||||
* @param args Arguments referenced by the format specifiers in the format string. If the last
|
||||
@ -270,16 +295,17 @@ public class Log {
|
||||
String message = formatLog(messageTemplate, args);
|
||||
Throwable tr = getThrowableToLog(args);
|
||||
if (tr != null) {
|
||||
android.util.Log.w(tag, message, tr);
|
||||
android.util.Log.w(normalizeTag(tag), message, tr);
|
||||
} else {
|
||||
android.util.Log.w(tag, message);
|
||||
android.util.Log.w(normalizeTag(tag), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an {@link android.util.Log#ERROR} log message.
|
||||
*
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tag Used to identify the source of a log message. Might be modified in the output
|
||||
* (see {@link #normalizeTag(String)})
|
||||
* @param messageTemplate The message you would like logged. It is to be specified as a format
|
||||
* string.
|
||||
* @param args Arguments referenced by the format specifiers in the format string. If the last
|
||||
@ -290,9 +316,9 @@ public class Log {
|
||||
String message = formatLog(messageTemplate, args);
|
||||
Throwable tr = getThrowableToLog(args);
|
||||
if (tr != null) {
|
||||
android.util.Log.e(tag, message, tr);
|
||||
android.util.Log.e(normalizeTag(tag), message, tr);
|
||||
} else {
|
||||
android.util.Log.e(tag, message);
|
||||
android.util.Log.e(normalizeTag(tag), message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +329,8 @@ public class Log {
|
||||
*
|
||||
* @see android.util.Log#wtf(String, String, Throwable)
|
||||
*
|
||||
* @param tag Used to identify the source of a log message.
|
||||
* @param tag Used to identify the source of a log message. Might be modified in the output
|
||||
* (see {@link #normalizeTag(String)})
|
||||
* @param messageTemplate The message you would like logged. It is to be specified as a format
|
||||
* string.
|
||||
* @param args Arguments referenced by the format specifiers in the format string. If the last
|
||||
@ -314,9 +341,9 @@ public class Log {
|
||||
String message = formatLog(messageTemplate, args);
|
||||
Throwable tr = getThrowableToLog(args);
|
||||
if (tr != null) {
|
||||
android.util.Log.wtf(tag, message, tr);
|
||||
android.util.Log.wtf(normalizeTag(tag), message, tr);
|
||||
} else {
|
||||
android.util.Log.wtf(tag, message);
|
||||
android.util.Log.wtf(normalizeTag(tag), message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,14 @@ public class LogTest {
|
||||
logs.get(0).msg.matches("\\[LogTest.java:\\d+\\].*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalizeTagTest() {
|
||||
assertEquals("cr_foo", Log.normalizeTag("cr.foo"));
|
||||
assertEquals("cr_foo", Log.normalizeTag("cr_foo"));
|
||||
assertEquals("cr_foo", Log.normalizeTag("foo"));
|
||||
assertEquals("cr_ab_foo", Log.normalizeTag("ab_foo"));
|
||||
}
|
||||
|
||||
/** Tests that exceptions provided to the log functions are properly recognized and printed. */
|
||||
@Test
|
||||
public void exceptionLoggingTest() {
|
||||
|
192
chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionCallableTest.java
192
chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionCallableTest.java
@ -4,17 +4,10 @@
|
||||
|
||||
package org.chromium.chrome.browser.crash;
|
||||
|
||||
import static org.chromium.chrome.browser.crash.LogcatExtractionCallable.BEGIN_MICRODUMP;
|
||||
import static org.chromium.chrome.browser.crash.LogcatExtractionCallable.END_MICRODUMP;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.test.MoreAsserts;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.chromium.base.test.util.AdvancedMockContext;
|
||||
|
||||
@ -22,11 +15,7 @@ import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@ -36,192 +25,11 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
public class LogcatExtractionCallableTest extends CrashTestCase {
|
||||
private File mCrashDir;
|
||||
|
||||
private static final int MAX_LINES = 5;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mCrashDir = new CrashFileManager(mCacheDir).getCrashDirectory();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideEmail() {
|
||||
String original = "email me at someguy@mailservice.com";
|
||||
String expected = "email me at XXX@EMAIL.ELIDED";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideEmail(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideUrl() {
|
||||
String original = "file bugs at crbug.com";
|
||||
String expected = "file bugs at HTTP://WEBADDRESS.ELIDED";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideUrl2() {
|
||||
String original =
|
||||
"exception at org.chromium.chrome.browser.crash.LogcatExtractionCallableTest";
|
||||
assertEquals(original, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideUrl3() {
|
||||
String original = "file bugs at crbug.com or code.google.com";
|
||||
String expected = "file bugs at HTTP://WEBADDRESS.ELIDED or HTTP://WEBADDRESS.ELIDED";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideUrl4() {
|
||||
String original = "test shorturl.com !!!";
|
||||
String expected = "test HTTP://WEBADDRESS.ELIDED !!!";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideUrl5() {
|
||||
String original = "test just.the.perfect.len.url !!!";
|
||||
String expected = "test HTTP://WEBADDRESS.ELIDED !!!";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideUrl6() {
|
||||
String original = "test a.very.very.very.very.very.long.url !!!";
|
||||
String expected = "test HTTP://WEBADDRESS.ELIDED !!!";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideUrl7() {
|
||||
String original = " at android.content.Intent \n at java.util.ArrayList";
|
||||
assertEquals(original, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideIp() {
|
||||
String original = "traceroute 127.0.0.1";
|
||||
String expected = "traceroute 1.2.3.4";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideIp(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideMac1() {
|
||||
String original = "MAC: AB-AB-AB-AB-AB-AB";
|
||||
String expected = "MAC: 01:23:45:67:89:AB";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideMac(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideMac2() {
|
||||
String original = "MAC: AB:AB:AB:AB:AB:AB";
|
||||
String expected = "MAC: 01:23:45:67:89:AB";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideMac(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testElideConsole() {
|
||||
String original = "I/chromium(123): [INFO:CONSOLE(2)] hello!";
|
||||
String expected = "I/chromium(123): [ELIDED:CONSOLE(0)] ELIDED CONSOLE MESSAGE";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideConsole(original));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatEmpty() {
|
||||
final String original = "";
|
||||
List<String> expected = new LinkedList<>();
|
||||
List<String> logcat = null;
|
||||
try {
|
||||
logcat = LogcatExtractionCallable.extractLogcatFromReader(
|
||||
new BufferedReader(new StringReader(original)), MAX_LINES);
|
||||
} catch (Exception e) {
|
||||
fail(e.toString());
|
||||
}
|
||||
MoreAsserts.assertEquals(expected.toArray(), logcat.toArray());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithoutBeginOrEnd_smallLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4",
|
||||
"Line 5");
|
||||
assertLogcatLists(original, original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithoutBeginOrEnd_largeLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4",
|
||||
"Line 5", "Redundant Line 1", "Redundant Line 2");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4",
|
||||
"Line 5");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatBeginsWithBegin() {
|
||||
final List<String> original = Arrays.asList(BEGIN_MICRODUMP, "a", "b", "c", "d", "e");
|
||||
assertLogcatLists(new LinkedList<String>(), original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithBegin() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", BEGIN_MICRODUMP, "a",
|
||||
"b", "c", "d", "e");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithEnd() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", END_MICRODUMP);
|
||||
assertLogcatLists(new LinkedList<String>(), original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithBeginAndEnd_smallLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", BEGIN_MICRODUMP, "a", "b",
|
||||
"c", "d", "e", END_MICRODUMP);
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithBeginAndEnd_largeLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", BEGIN_MICRODUMP, "a", "b",
|
||||
"c", "d", "e", END_MICRODUMP, "Line 3", "Line 4");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithEndAndBegin_smallLogcat() {
|
||||
final List<String> original = Arrays.asList(END_MICRODUMP, "Line 1", "Line 2",
|
||||
BEGIN_MICRODUMP, "a", "b", "c", "d", "e");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testLogcatWithEndAndBegin_largeLogcat() {
|
||||
final List<String> original = Arrays.asList(END_MICRODUMP, "Line 1", "Line 2",
|
||||
BEGIN_MICRODUMP, "a", "b", "c", "d", "e", END_MICRODUMP, "Line 3", "Line 4");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
private void assertLogcatLists(List<String> expected, List<String> original) {
|
||||
List<String> actualLogcat = null;
|
||||
String combinedLogcat = TextUtils.join("\n", original);
|
||||
try {
|
||||
//simulate a file reader to test whether the extraction process
|
||||
//successfully strips microdump from logcat
|
||||
actualLogcat = LogcatExtractionCallable.extractLogcatFromReader(
|
||||
new BufferedReader(new StringReader(combinedLogcat)), MAX_LINES);
|
||||
} catch (Exception e) {
|
||||
fail(e.toString());
|
||||
}
|
||||
MoreAsserts.assertEquals(expected.toArray(), actualLogcat.toArray());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testExtractToFile() {
|
||||
final AtomicInteger numServiceStarts = new AtomicInteger(0);
|
||||
|
218
chrome/android/junit/src/org/chromium/chrome/browser/crash/LogcatExtractionCallableTest.java
Normal file
218
chrome/android/junit/src/org/chromium/chrome/browser/crash/LogcatExtractionCallableTest.java
Normal file
@ -0,0 +1,218 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.chrome.browser.crash;
|
||||
|
||||
import static org.chromium.chrome.browser.crash.LogcatExtractionCallable.BEGIN_MICRODUMP;
|
||||
import static org.chromium.chrome.browser.crash.LogcatExtractionCallable.END_MICRODUMP;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.chromium.testing.local.LocalRobolectricTestRunner;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* junit tests for {@link LogcatExtractionCallable}.
|
||||
*/
|
||||
@RunWith(LocalRobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE)
|
||||
public class LogcatExtractionCallableTest {
|
||||
private static final int MAX_LINES = 5;
|
||||
|
||||
@Test
|
||||
public void testElideEmail() {
|
||||
String original = "email me at someguy@mailservice.com";
|
||||
String expected = "email me at XXX@EMAIL.ELIDED";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideEmail(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideUrl() {
|
||||
String original = "file bugs at crbug.com";
|
||||
String expected = "file bugs at HTTP://WEBADDRESS.ELIDED";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideUrl2() {
|
||||
String original =
|
||||
"exception at org.chromium.chrome.browser.crash.LogcatExtractionCallableTest";
|
||||
assertEquals(original, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideUrl3() {
|
||||
String original = "file bugs at crbug.com or code.google.com";
|
||||
String expected = "file bugs at HTTP://WEBADDRESS.ELIDED or HTTP://WEBADDRESS.ELIDED";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideUrl4() {
|
||||
String original = "test shorturl.com !!!";
|
||||
String expected = "test HTTP://WEBADDRESS.ELIDED !!!";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideUrl5() {
|
||||
String original = "test just.the.perfect.len.url !!!";
|
||||
String expected = "test HTTP://WEBADDRESS.ELIDED !!!";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideUrl6() {
|
||||
String original = "test a.very.very.very.very.very.long.url !!!";
|
||||
String expected = "test HTTP://WEBADDRESS.ELIDED !!!";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideUrl7() {
|
||||
String original = " at android.content.Intent \n at java.util.ArrayList";
|
||||
assertEquals(original, LogcatExtractionCallable.elideUrl(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideIp() {
|
||||
String original = "traceroute 127.0.0.1";
|
||||
String expected = "traceroute 1.2.3.4";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideIp(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideMac1() {
|
||||
String original = "MAC: AB-AB-AB-AB-AB-AB";
|
||||
String expected = "MAC: 01:23:45:67:89:AB";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideMac(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideMac2() {
|
||||
String original = "MAC: AB:AB:AB:AB:AB:AB";
|
||||
String expected = "MAC: 01:23:45:67:89:AB";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideMac(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElideConsole() {
|
||||
String original = "I/chromium(123): [INFO:CONSOLE(2)] hello!";
|
||||
String expected = "I/chromium(123): [ELIDED:CONSOLE(0)] ELIDED CONSOLE MESSAGE";
|
||||
assertEquals(expected, LogcatExtractionCallable.elideConsole(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogTagNotElided() {
|
||||
List<String> original = Arrays.asList(new String[] {"I/cr_FooBar(123): Some message"});
|
||||
assertEquals(original, LogcatExtractionCallable.processLogcat(original));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatEmpty() {
|
||||
final String original = "";
|
||||
List<String> expected = new LinkedList<>();
|
||||
List<String> logcat = null;
|
||||
try {
|
||||
logcat = LogcatExtractionCallable.extractLogcatFromReader(
|
||||
new BufferedReader(new StringReader(original)), MAX_LINES);
|
||||
} catch (Exception e) {
|
||||
fail(e.toString());
|
||||
}
|
||||
assertArrayEquals(expected.toArray(), logcat.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithoutBeginOrEnd_smallLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4",
|
||||
"Line 5");
|
||||
assertLogcatLists(original, original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithoutBeginOrEnd_largeLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4",
|
||||
"Line 5", "Redundant Line 1", "Redundant Line 2");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4",
|
||||
"Line 5");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatBeginsWithBegin() {
|
||||
final List<String> original = Arrays.asList(BEGIN_MICRODUMP, "a", "b", "c", "d", "e");
|
||||
assertLogcatLists(new LinkedList<String>(), original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithBegin() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", BEGIN_MICRODUMP, "a",
|
||||
"b", "c", "d", "e");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithEnd() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", END_MICRODUMP);
|
||||
assertLogcatLists(new LinkedList<String>(), original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithBeginAndEnd_smallLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", BEGIN_MICRODUMP, "a", "b",
|
||||
"c", "d", "e", END_MICRODUMP);
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithBeginAndEnd_largeLogcat() {
|
||||
final List<String> original = Arrays.asList("Line 1", "Line 2", BEGIN_MICRODUMP, "a", "b",
|
||||
"c", "d", "e", END_MICRODUMP, "Line 3", "Line 4");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithEndAndBegin_smallLogcat() {
|
||||
final List<String> original = Arrays.asList(END_MICRODUMP, "Line 1", "Line 2",
|
||||
BEGIN_MICRODUMP, "a", "b", "c", "d", "e");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogcatWithEndAndBegin_largeLogcat() {
|
||||
final List<String> original = Arrays.asList(END_MICRODUMP, "Line 1", "Line 2",
|
||||
BEGIN_MICRODUMP, "a", "b", "c", "d", "e", END_MICRODUMP, "Line 3", "Line 4");
|
||||
final List<String> expected = Arrays.asList("Line 1", "Line 2", "Line 3", "Line 4");
|
||||
assertLogcatLists(expected, original);
|
||||
}
|
||||
|
||||
private void assertLogcatLists(List<String> expected, List<String> original) {
|
||||
List<String> actualLogcat = null;
|
||||
String combinedLogcat = TextUtils.join("\n", original);
|
||||
try {
|
||||
//simulate a file reader to test whether the extraction process
|
||||
//successfully strips microdump from logcat
|
||||
actualLogcat = LogcatExtractionCallable.extractLogcatFromReader(
|
||||
new BufferedReader(new StringReader(combinedLogcat)), MAX_LINES);
|
||||
} catch (Exception e) {
|
||||
fail(e.toString());
|
||||
}
|
||||
assertArrayEquals(expected.toArray(), actualLogcat.toArray());
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ make it easy to switch logging on or off for individual groups.
|
||||
Usage:
|
||||
|
||||
```java
|
||||
private static final String TAG = "cr.YourModuleTag";
|
||||
private static final String TAG = "YourModuleTag";
|
||||
...
|
||||
Log.i(TAG, "Logged INFO message.");
|
||||
Log.d(TAG, "Some DEBUG info: %s", data);
|
||||
@ -24,12 +24,13 @@ Log.d(TAG, "Some DEBUG info: %s", data);
|
||||
Output:
|
||||
|
||||
```
|
||||
I/cr.YourModuleTag: ( 999): Logged INFO message
|
||||
D/cr.YourModuleTag: ( 999): [MyClass.java:42] Some DEBUG info: data.toString
|
||||
I/cr_YourModuleTag: ( 999): Logged INFO message
|
||||
D/cr_YourModuleTag: ( 999): [MyClass.java:42] Some DEBUG info: data.toString
|
||||
```
|
||||
|
||||
Here, **TAG** will be a feature or package name, "MediaRemote" or "NFC" for
|
||||
example. In most cases, the class name is not needed.
|
||||
example. In most cases, the class name is not needed. It will be prepended by
|
||||
the "cr_" prefix to make obvious which logs are coming from Chrome.
|
||||
|
||||
### Verbose and Debug logs have special handling ###
|
||||
|
||||
@ -50,10 +51,10 @@ Log.i(TAG, "An error happened: %s", e)
|
||||
```
|
||||
|
||||
```
|
||||
I/cr.YourModuleTag: ( 999): An error happened: This is the exception's message
|
||||
I/cr.YourModuleTag: ( 999): java.lang.Exception: This is the exception's message
|
||||
I/cr.YourModuleTag: ( 999): at foo.bar.MyClass.test(MyClass.java:42)
|
||||
I/cr.YourModuleTag: ( 999): ...
|
||||
I/cr_YourModuleTag: ( 999): An error happened: This is the exception's message
|
||||
I/cr_YourModuleTag: ( 999): java.lang.Exception: This is the exception's message
|
||||
I/cr_YourModuleTag: ( 999): at foo.bar.MyClass.test(MyClass.java:42)
|
||||
I/cr_YourModuleTag: ( 999): ...
|
||||
```
|
||||
|
||||
Having the exception as last parameter doesn't prevent it from being used for
|
||||
@ -187,16 +188,16 @@ Logcat allows filtering by specifying tags and the associated level:
|
||||
|
||||
```shell
|
||||
adb logcat [TAG_EXPR:LEVEL]...
|
||||
adb logcat cr.YourModuleTag:D *:S
|
||||
adb logcat cr_YourModuleTag:D *:S
|
||||
```
|
||||
|
||||
This shows only logs having a level higher or equal to DEBUG for
|
||||
`cr.YourModuleTag`, and SILENT (nothing is logged at this level or higher, so it
|
||||
`cr_YourModuleTag`, and SILENT (nothing is logged at this level or higher, so it
|
||||
silences the tags) for everything else. You can persist a filter by setting an
|
||||
environment variable:
|
||||
|
||||
```shell
|
||||
export ANDROID_LOG_TAGS="cr.YourModuleTag:D *:S"
|
||||
export ANDROID_LOG_TAGS="cr_YourModuleTag:D *:S"
|
||||
```
|
||||
|
||||
For more, see the [related page on developer.android.com]
|
||||
|
Reference in New Issue
Block a user