Commit c0fe43c4 authored by Azhara Assanova's avatar Azhara Assanova Committed by Commit Bot

[AW][Dev-UI] Unit tests for hide crash button methods

1. testMergeDuplicatesAndHidden: checks that hidden crashes are removed
from the returning list
2. testUploadCrashLogFileWithNewCrashInfo: checks that updates the crash
JSON log file with the new crash info

Bug: 1059944
Test: run_webview_instrumentation_test_apk -f *WebViewCrashInfoCollectorTest*
Change-Id: Id465000b2035a4efa91b59399ca961122e8fae4e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2379777Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Reviewed-by: default avatarHazem Ashmawy <hazems@chromium.org>
Reviewed-by: default avatarLaís Minchillo <laisminchillo@chromium.org>
Commit-Queue: Azhara Assanova <azharaa@google.com>
Auto-Submit: Azhara Assanova <azharaa@google.com>
Cr-Commit-Position: refs/heads/master@{#805265}
parent 76b494d4
...@@ -72,7 +72,7 @@ public class CrashInfo { ...@@ -72,7 +72,7 @@ public class CrashInfo {
private static final String CRASH_CAPTURE_TIME_KEY = "crash-capture-time"; private static final String CRASH_CAPTURE_TIME_KEY = "crash-capture-time";
private static final String CRASH_UPLOAD_ID_KEY = "crash-upload-id"; private static final String CRASH_UPLOAD_ID_KEY = "crash-upload-id";
private static final String CRASH_UPLOAD_TIME_KEY = "crash-upload-time"; private static final String CRASH_UPLOAD_TIME_KEY = "crash-upload-time";
private static final String CRASH_IS_HIDDEN = "crash-is-hidden"; private static final String CRASH_IS_HIDDEN_KEY = "crash-is-hidden";
private static final String CRASH_KEYS_KEY = "crash-keys"; private static final String CRASH_KEYS_KEY = "crash-keys";
// Should match the crash keys used in minidump reports see for example of some keys: // Should match the crash keys used in minidump reports see for example of some keys:
// {@link android_webview/common/crash_reporter/crash_keys.cc} // {@link android_webview/common/crash_reporter/crash_keys.cc}
...@@ -179,7 +179,7 @@ public class CrashInfo { ...@@ -179,7 +179,7 @@ public class CrashInfo {
if (uploadTime != -1) { if (uploadTime != -1) {
jsonObj.put(CRASH_UPLOAD_TIME_KEY, uploadTime); jsonObj.put(CRASH_UPLOAD_TIME_KEY, uploadTime);
} }
jsonObj.put(CRASH_IS_HIDDEN, isHidden); jsonObj.put(CRASH_IS_HIDDEN_KEY, isHidden);
jsonObj.put(CRASH_KEYS_KEY, new JSONObject(mCrashKeys)); jsonObj.put(CRASH_KEYS_KEY, new JSONObject(mCrashKeys));
return jsonObj.toString(); return jsonObj.toString();
} catch (JSONException e) { } catch (JSONException e) {
...@@ -214,8 +214,8 @@ public class CrashInfo { ...@@ -214,8 +214,8 @@ public class CrashInfo {
crashInfo.uploadTime = jsonObj.getLong(CRASH_UPLOAD_TIME_KEY); crashInfo.uploadTime = jsonObj.getLong(CRASH_UPLOAD_TIME_KEY);
} }
if (jsonObj.has(CRASH_IS_HIDDEN)) { if (jsonObj.has(CRASH_IS_HIDDEN_KEY)) {
crashInfo.isHidden = jsonObj.getBoolean(CRASH_IS_HIDDEN); crashInfo.isHidden = jsonObj.getBoolean(CRASH_IS_HIDDEN_KEY);
} }
if (jsonObj.has(CRASH_KEYS_KEY)) { if (jsonObj.has(CRASH_KEYS_KEY)) {
......
...@@ -88,6 +88,11 @@ public class CrashInfoEqualityMatcher extends BaseMatcher<CrashInfo> { ...@@ -88,6 +88,11 @@ public class CrashInfoEqualityMatcher extends BaseMatcher<CrashInfo> {
builder.append(String.format(Locale.US, MISMATCH_STRING_FORMAT, "captureTime", builder.append(String.format(Locale.US, MISMATCH_STRING_FORMAT, "captureTime",
c.captureTime, mCrashInfo.captureTime)); c.captureTime, mCrashInfo.captureTime));
} }
if (mCrashInfo.isHidden != c.isHidden) {
builder.append(String.format(Locale.US, MISMATCH_STRING_FORMAT, "isHidden", c.isHidden,
mCrashInfo.isHidden));
}
// empty means a match // empty means a match
return builder.length() == 0 ? null : builder.toString(); return builder.length() == 0 ? null : builder.toString();
} }
......
...@@ -50,6 +50,20 @@ public class CrashInfoTest { ...@@ -50,6 +50,20 @@ public class CrashInfoTest {
return crashInfo; return crashInfo;
} }
/**
* Create a hidden {@link CrashInfo} object for testing.
*
* {@code appPackageName} is used as a representative of crash keys in tests.
*/
public static CrashInfo createHiddenCrashInfo(String localId, long captureTime, String uploadId,
long uploadTime, String appPackageName, UploadState state) {
CrashInfo crashInfo =
createCrashInfo(localId, captureTime, uploadId, uploadTime, appPackageName, state);
crashInfo.isHidden = true;
return crashInfo;
}
/** /**
* Test that merging two {@code CrashInfo} objects works correctly. * Test that merging two {@code CrashInfo} objects works correctly.
*/ */
......
...@@ -4,28 +4,38 @@ ...@@ -4,28 +4,38 @@
package org.chromium.android_webview.test.devui.util; package org.chromium.android_webview.test.devui.util;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS; import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS;
import static org.chromium.android_webview.test.common.crash.CrashInfoEqualityMatcher.equalsTo; import static org.chromium.android_webview.test.common.crash.CrashInfoEqualityMatcher.equalsTo;
import static org.chromium.android_webview.test.common.crash.CrashInfoTest.createCrashInfo; import static org.chromium.android_webview.test.common.crash.CrashInfoTest.createCrashInfo;
import static org.chromium.android_webview.test.common.crash.CrashInfoTest.createHiddenCrashInfo;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import org.json.JSONException;
import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.chromium.android_webview.common.crash.CrashInfo; import org.chromium.android_webview.common.crash.CrashInfo;
import org.chromium.android_webview.common.crash.CrashInfo.UploadState; import org.chromium.android_webview.common.crash.CrashInfo.UploadState;
import org.chromium.android_webview.common.crash.SystemWideCrashDirectories;
import org.chromium.android_webview.devui.util.CrashInfoLoader; import org.chromium.android_webview.devui.util.CrashInfoLoader;
import org.chromium.android_webview.devui.util.WebViewCrashInfoCollector; import org.chromium.android_webview.devui.util.WebViewCrashInfoCollector;
import org.chromium.android_webview.devui.util.WebViewCrashInfoCollector.CrashInfoLoadersFactory; import org.chromium.android_webview.devui.util.WebViewCrashInfoCollector.CrashInfoLoadersFactory;
import org.chromium.android_webview.devui.util.WebViewCrashLogParser;
import org.chromium.android_webview.test.AwJUnit4ClassRunner; import org.chromium.android_webview.test.AwJUnit4ClassRunner;
import org.chromium.android_webview.test.OnlyRunIn; import org.chromium.android_webview.test.OnlyRunIn;
import org.chromium.base.FileUtils;
import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.Batch;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
...@@ -55,6 +65,33 @@ public class WebViewCrashInfoCollectorTest { ...@@ -55,6 +65,33 @@ public class WebViewCrashInfoCollectorTest {
} }
} }
@After
public void tearDown() {
FileUtils.recursivelyDeleteFile(SystemWideCrashDirectories.getWebViewCrashLogDir(), null);
}
private static File writeJsonLogFile(CrashInfo crashInfo) throws IOException {
File dir = SystemWideCrashDirectories.getOrCreateWebViewCrashLogDir();
File jsonFile = File.createTempFile(crashInfo.localId, ".json", dir);
FileWriter writer = new FileWriter(jsonFile);
writer.write(crashInfo.serializeToJson());
writer.close();
return jsonFile;
}
private static CrashInfo getCrashFromJsonLogFile(String localId)
throws IOException, JSONException {
File logDir = SystemWideCrashDirectories.getOrCreateWebViewCrashLogDir();
File[] logFiles = logDir.listFiles();
for (File logFile : logFiles) {
if (!logFile.isFile() || !logFile.getName().endsWith(".json")) continue;
if (!logFile.getName().contains(localId)) continue;
String jsonObject = WebViewCrashLogParser.readEntireFile(logFile);
return CrashInfo.readFromJsonString(jsonObject);
}
return null;
}
/** /**
* Test that merging {@code CrashInfo} that has the same {@code localID} works correctly. * Test that merging {@code CrashInfo} that has the same {@code localID} works correctly.
*/ */
...@@ -81,6 +118,28 @@ public class WebViewCrashInfoCollectorTest { ...@@ -81,6 +118,28 @@ public class WebViewCrashInfoCollectorTest {
UploadState.UPLOADED)))); UploadState.UPLOADED))));
} }
/**
* Test that merging hidden {@code CrashInfo} that has the same {@code localID} works correctly.
*/
@Test
@SmallTest
public void testMergeDuplicatesAndIgnoreHidden() {
List<CrashInfo> testList = Arrays.asList(
createHiddenCrashInfo("xyz123", 112233445566L, null, -1, null, UploadState.PENDING),
createCrashInfo(
"def789", -1, "55667788", 123344556677L, null, UploadState.UPLOADED),
createHiddenCrashInfo("abc456", -1, null, -1, null, UploadState.PENDING),
createCrashInfo("xyz123", 112233445566L, null, -1, "com.test.package", null),
createCrashInfo("abc456", 445566778899L, null, -1, "org.test.package", null),
createCrashInfo("abc456", -1, null, -1, null, null),
createCrashInfo(
"xyz123", -1, "11223344", 223344556677L, null, UploadState.UPLOADED));
List<CrashInfo> uniqueList = WebViewCrashInfoCollector.mergeDuplicates(testList);
Assert.assertThat(uniqueList,
containsInAnyOrder(equalsTo(createCrashInfo(
"def789", -1, "55667788", 123344556677L, null, UploadState.UPLOADED))));
}
/** /**
* Test that sort method works correctly; it sorts by recent crashes first (capture time then * Test that sort method works correctly; it sorts by recent crashes first (capture time then
* upload time). * upload time).
...@@ -142,4 +201,35 @@ public class WebViewCrashInfoCollectorTest { ...@@ -142,4 +201,35 @@ public class WebViewCrashInfoCollectorTest {
equalsTo(createCrashInfo("def789", -1, "55667788", 123344556677L, null, equalsTo(createCrashInfo("def789", -1, "55667788", 123344556677L, null,
UploadState.UPLOADED)))); UploadState.UPLOADED))));
} }
/**
* Test updating crash JSON log file with the new crash info
*/
@Test
@SmallTest
public void testUpdateCrashLogFileWithNewCrashInfo() throws Throwable {
CrashInfo oldCrashInfo = createCrashInfo("xyz123", 112233445566L, null, -1, null, null);
assertThat("temp json log file should exist", writeJsonLogFile(oldCrashInfo).exists());
CrashInfo newCrashInfo =
createHiddenCrashInfo("xyz123", 112233445566L, null, -1, "com.test.package", null);
WebViewCrashInfoCollector.updateCrashLogFileWithNewCrashInfo(newCrashInfo);
CrashInfo resultCrashInfo = getCrashFromJsonLogFile("xyz123");
Assert.assertThat(resultCrashInfo, equalsTo(newCrashInfo));
}
/**
* Test updating non-existing crash JSON log file with the new crash info
*/
@Test
@SmallTest
public void testUpdateNonExistingCrashLogFileWithNewCrashInfo() throws Throwable {
CrashInfo newCrashInfo =
createHiddenCrashInfo("xyz123", 112233445566L, null, -1, "com.test.package", null);
WebViewCrashInfoCollector.updateCrashLogFileWithNewCrashInfo(newCrashInfo);
CrashInfo resultCrashInfo = getCrashFromJsonLogFile("xyz123");
Assert.assertThat(resultCrashInfo, equalsTo(null));
}
} }
...@@ -148,6 +148,9 @@ public class WebViewCrashInfoCollector { ...@@ -148,6 +148,9 @@ public class WebViewCrashInfoCollector {
public static void updateCrashLogFileWithNewCrashInfo(CrashInfo crashInfo) { public static void updateCrashLogFileWithNewCrashInfo(CrashInfo crashInfo) {
File logDir = SystemWideCrashDirectories.getWebViewCrashLogDir(); File logDir = SystemWideCrashDirectories.getWebViewCrashLogDir();
File[] logFiles = logDir.listFiles(); File[] logFiles = logDir.listFiles();
if (logFiles == null) {
return;
}
for (File logFile : logFiles) { for (File logFile : logFiles) {
// Ignore non-json files. // Ignore non-json files.
if (!logFile.isFile() || !logFile.getName().endsWith(".json")) continue; if (!logFile.isFile() || !logFile.getName().endsWith(".json")) continue;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.android_webview.devui.util; package org.chromium.android_webview.devui.util;
import androidx.annotation.VisibleForTesting;
import org.json.JSONException; import org.json.JSONException;
import org.chromium.android_webview.common.crash.CrashInfo; import org.chromium.android_webview.common.crash.CrashInfo;
...@@ -69,7 +71,8 @@ public class WebViewCrashLogParser extends CrashInfoLoader { ...@@ -69,7 +71,8 @@ public class WebViewCrashLogParser extends CrashInfoLoader {
return infoList; return infoList;
} }
private static String readEntireFile(File file) throws IOException { @VisibleForTesting
public static String readEntireFile(File file) throws IOException {
try (FileInputStream fileInputStream = new FileInputStream(file)) { try (FileInputStream fileInputStream = new FileInputStream(file)) {
byte[] data = new byte[(int) file.length()]; byte[] data = new byte[(int) file.length()];
fileInputStream.read(data); fileInputStream.read(data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment