Index: android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java |
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java |
index 8ceb0c30a52f2c607080f255ff14b6dd4253d3f7..c627cc1367ff1c5fae784c27ff5c8315412ed8f3 100644 |
--- a/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java |
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/crash/MinidumpUploaderTest.java |
@@ -7,7 +7,6 @@ package org.chromium.android_webview.test.crash; |
import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; |
import android.content.Context; |
-import android.os.ParcelFileDescriptor; |
import android.support.test.filters.MediumTest; |
import android.webkit.ValueCallback; |
@@ -17,7 +16,6 @@ import org.chromium.android_webview.crash.MinidumpUploader; |
import org.chromium.android_webview.crash.MinidumpUploaderImpl; |
import org.chromium.base.FileUtils; |
import org.chromium.base.ThreadUtils; |
-import org.chromium.components.minidump_uploader.CrashFileManager; |
import org.chromium.components.minidump_uploader.CrashTestCase; |
import org.chromium.components.minidump_uploader.MinidumpUploadCallable; |
import org.chromium.components.minidump_uploader.MinidumpUploadCallableTest; |
@@ -25,8 +23,6 @@ import org.chromium.components.minidump_uploader.util.CrashReportingPermissionMa |
import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory; |
import java.io.File; |
-import java.io.FileInputStream; |
-import java.io.FileNotFoundException; |
import java.io.IOException; |
import java.io.InterruptedIOException; |
import java.io.OutputStream; |
@@ -42,8 +38,7 @@ import java.util.concurrent.TimeUnit; |
* Instrumentation tests for MinidumpUploader. |
*/ |
public class MinidumpUploaderTest extends CrashTestCase { |
- private static final String TAG = "MinidumpUploaderTest"; |
- private static final String BOUNDARY = "TESTBOUNDARY"; |
+ protected static final String BOUNDARY = "TESTBOUNDARY"; |
private static final long TIME_OUT_MILLIS = 3000; |
@@ -52,7 +47,11 @@ public class MinidumpUploaderTest extends CrashTestCase { |
return CrashReceiverService.createWebViewCrashDir(getInstrumentation().getTargetContext()); |
} |
- private static class TestPlatformServiceBridge extends PlatformServiceBridge { |
+ /** |
+ * An implementation of PlatformServiceBridge that just returns a user-consent value directly |
+ * when queried. |
+ */ |
+ protected static class TestPlatformServiceBridge extends PlatformServiceBridge { |
boolean mCanUseGms; |
boolean mUserPermitted; |
@@ -73,7 +72,10 @@ public class MinidumpUploaderTest extends CrashTestCase { |
} |
} |
- private static class TestMinidumpUploaderImpl extends MinidumpUploaderImpl { |
+ /** |
+ * A convenience-implementation of MinidumpUploader. |
+ */ |
+ protected static class TestMinidumpUploaderImpl extends MinidumpUploaderImpl { |
private CrashReportingPermissionManager mPermissionManager; |
TestMinidumpUploaderImpl(Context context, CrashReportingPermissionManager permissionManager, |
@@ -172,7 +174,10 @@ public class MinidumpUploaderTest extends CrashTestCase { |
} |
} |
- private static void uploadMinidumpsSync( |
+ /** |
+ * Upload minidumps on the UI thread, and wait until all uploads are done. |
+ */ |
+ protected static void uploadMinidumpsSync( |
MinidumpUploader minidumpUploader, final boolean expectReschedule) { |
final CountDownLatch uploadsFinishedLatch = new CountDownLatch(1); |
uploadAllMinidumpsOnUiThread( |
@@ -417,262 +422,7 @@ public class MinidumpUploaderTest extends CrashTestCase { |
} |
} |
- /** |
- * Ensures that the minidump copying works together with the minidump uploading. |
- */ |
- @MediumTest |
- public void testCopyAndUploadWebViewMinidump() throws FileNotFoundException, IOException { |
- final CrashFileManager fileManager = new CrashFileManager( |
- CrashReceiverService.getWebViewCrashDir(getInstrumentation().getTargetContext())); |
- // Note that these minidump files are set up directly in the cache dir - not in the WebView |
- // crash dir. This is to ensure the CrashFileManager doesn't see these minidumps without us |
- // first copying them. |
- File minidumpToCopy = |
- new File(getInstrumentation().getTargetContext().getCacheDir(), "toCopy.dmp"); |
- setUpMinidumpFile(minidumpToCopy, BOUNDARY, "browser"); |
- final String expectedFileContent = readEntireFile(minidumpToCopy); |
- |
- File[] uploadedFiles = copyAndUploadMinidumpsSync( |
- fileManager, new File[][] {{minidumpToCopy}}, new int[] {0}); |
- |
- // CrashReceiverService will rename the minidumps to some globally unique file name |
- // meaning that we have to check the contents of the minidump rather than the file |
- // name. |
- try { |
- assertEquals(expectedFileContent, readEntireFile(uploadedFiles[0])); |
- } catch (IOException e) { |
- throw new RuntimeException(e); |
- } |
- File webviewTmpDir = |
- CrashReceiverService.getWebViewTmpCrashDir(getInstrumentation().getTargetContext()); |
- assertEquals(0, webviewTmpDir.listFiles().length); |
- } |
- |
- /** |
- * Ensure that when PlatformServiceBridge returns true we do upload minidumps. |
- */ |
- @MediumTest |
- public void testPlatformServicesBridgeIsUsedUserConsent() throws IOException { |
- testPlatformServicesBridgeIsUsed(true); |
- } |
- |
- /** |
- * Ensure that when PlatformServiceBridge returns false we do not upload minidumps. |
- */ |
- @MediumTest |
- public void testPlatformServicesBridgeIsUsedNoUserConsent() throws IOException { |
- testPlatformServicesBridgeIsUsed(false); |
- } |
- |
- /** |
- * MinidumpUploaderImpl sub-class that uses MinidumpUploaderImpl's implementation of |
- * CrashReportingPermissionManager.isUsageAndCrashReportingPermittedByUser(). |
- */ |
- private static class WebViewUserConsentMinidumpUploaderImpl extends MinidumpUploaderImpl { |
- boolean mUserConsent; |
- WebViewUserConsentMinidumpUploaderImpl( |
- Context context, boolean cleanOutMinidumps, boolean userConsent) { |
- super(context, cleanOutMinidumps); |
- mUserConsent = userConsent; |
- } |
- @Override |
- public PlatformServiceBridge createPlatformServiceBridge() { |
- return new TestPlatformServiceBridge(true /* canUseGms */, mUserConsent); |
- } |
- @Override |
- public MinidumpUploadCallable createMinidumpUploadCallable( |
- File minidumpFile, File logfile) { |
- return new MinidumpUploadCallable(minidumpFile, logfile, |
- new MinidumpUploadCallableTest.TestHttpURLConnectionFactory(), |
- createWebViewCrashReportingManager()); |
- } |
- @Override |
- protected CrashReportingPermissionManager createWebViewCrashReportingManager() { |
- final CrashReportingPermissionManager realPermissionManager = |
- super.createWebViewCrashReportingManager(); |
- return new MockCrashReportingPermissionManager() { |
- { |
- // This setup ensures we depend on |
- // isUsageAndCrashReportingPermittedByUser(). |
- mIsInSample = true; |
- mIsPermitted = true; |
- mIsCommandLineDisabled = false; |
- mIsNetworkAvailable = true; |
- mIsEnabledForTests = false; |
- } |
- @Override |
- public boolean isUsageAndCrashReportingPermittedByUser() { |
- // Ensure that we use the real implementation of |
- // isUsageAndCrashReportingPermittedByUser. |
- boolean userPermitted = |
- realPermissionManager.isUsageAndCrashReportingPermittedByUser(); |
- assertEquals(mUserConsent, userPermitted); |
- return userPermitted; |
- } |
- }; |
- } |
- } |
- |
- private void testPlatformServicesBridgeIsUsed(final boolean userConsent) throws IOException { |
- MinidumpUploader minidumpUploader = |
- new WebViewUserConsentMinidumpUploaderImpl(getInstrumentation().getTargetContext(), |
- false /* cleanOutMinidumps */, userConsent); |
- |
- File firstFile = createMinidumpFileInCrashDir("1_abc.dmp0"); |
- File secondFile = createMinidumpFileInCrashDir("12_abcd.dmp0"); |
- File expectedFirstFile = new File( |
- mCrashDir, firstFile.getName().replace(".dmp", userConsent ? ".up" : ".skipped")); |
- File expectedSecondFile = new File( |
- mCrashDir, secondFile.getName().replace(".dmp", userConsent ? ".up" : ".skipped")); |
- |
- uploadMinidumpsSync(minidumpUploader, false /* expectReschedule */); |
- |
- assertFalse(firstFile.exists()); |
- assertTrue(expectedFirstFile.exists()); |
- assertFalse(secondFile.exists()); |
- assertTrue(expectedSecondFile.exists()); |
- } |
- |
- private static String readEntireFile(File file) throws IOException { |
- FileInputStream fileInputStream = new FileInputStream(file); |
- try { |
- byte[] data = new byte[(int) file.length()]; |
- fileInputStream.read(data); |
- return new String(data); |
- } finally { |
- fileInputStream.close(); |
- } |
- } |
- |
- /** |
- * Ensure that the minidump copying doesn't trigger when we pass it invalid file descriptors. |
- */ |
- @MediumTest |
- public void testCopyingAbortsForInvalidFds() throws FileNotFoundException, IOException { |
- assertFalse(CrashReceiverService.copyMinidumps( |
- getInstrumentation().getTargetContext(), 0 /* uid */, null)); |
- assertFalse(CrashReceiverService.copyMinidumps(getInstrumentation().getTargetContext(), |
- 0 /* uid */, new ParcelFileDescriptor[] {null, null})); |
- assertFalse(CrashReceiverService.copyMinidumps( |
- getInstrumentation().getTargetContext(), 0 /* uid */, new ParcelFileDescriptor[0])); |
- } |
- |
- /** |
- * Ensure deleting temporary files used when copying minidumps works correctly. |
- */ |
- @MediumTest |
- public void testDeleteFilesInDir() throws IOException { |
- Context context = getInstrumentation().getTargetContext(); |
- File webviewTmpDir = CrashReceiverService.getWebViewTmpCrashDir(context); |
- if (!webviewTmpDir.isDirectory()) { |
- assertTrue(webviewTmpDir.mkdir()); |
- } |
- File testFile1 = new File(webviewTmpDir, "testFile1"); |
- File testFile2 = new File(webviewTmpDir, "testFile2"); |
- assertTrue(testFile1.createNewFile()); |
- assertTrue(testFile2.createNewFile()); |
- assertTrue(testFile1.exists()); |
- assertTrue(testFile2.exists()); |
- CrashReceiverService.deleteFilesInWebViewTmpDirIfExists(context); |
- assertFalse(testFile1.exists()); |
- assertFalse(testFile2.exists()); |
- } |
- |
- /** |
- * Ensure we can copy and upload several batches of files (i.e. emulate several copying-calls in |
- * a row without the copying-service being destroyed in between). |
- */ |
- @MediumTest |
- public void testCopyAndUploadSeveralMinidumpBatches() throws IOException { |
- final CrashFileManager fileManager = new CrashFileManager( |
- CrashReceiverService.getWebViewCrashDir(getInstrumentation().getTargetContext())); |
- // Note that these minidump files are set up directly in the cache dir - not in the WebView |
- // crash dir. This is to ensure the CrashFileManager doesn't see these minidumps without us |
- // first copying them. |
- File firstMinidumpToCopy = |
- new File(getInstrumentation().getTargetContext().getCacheDir(), "firstToCopy.dmp"); |
- File secondMinidumpToCopy = |
- new File(getInstrumentation().getTargetContext().getCacheDir(), "secondToCopy.dmp"); |
- setUpMinidumpFile(firstMinidumpToCopy, BOUNDARY, "browser"); |
- setUpMinidumpFile(secondMinidumpToCopy, BOUNDARY, "renderer"); |
- final String expectedFirstFileContent = readEntireFile(firstMinidumpToCopy); |
- final String expectedSecondFileContent = readEntireFile(secondMinidumpToCopy); |
- |
- File[] uploadedFiles = copyAndUploadMinidumpsSync(fileManager, |
- new File[][] {{firstMinidumpToCopy}, {secondMinidumpToCopy}}, new int[] {0, 0}); |
- |
- // CrashReceiverService will rename the minidumps to some globally unique file name |
- // meaning that we have to check the contents of the minidump rather than the file |
- // name. |
- try { |
- final String actualFileContent0 = readEntireFile(uploadedFiles[0]); |
- final String actualFileContent1 = readEntireFile(uploadedFiles[1]); |
- if (expectedFirstFileContent.equals(actualFileContent0)) { |
- assertEquals(expectedSecondFileContent, actualFileContent1); |
- } else { |
- assertEquals(expectedFirstFileContent, actualFileContent1); |
- assertEquals(expectedSecondFileContent, actualFileContent0); |
- } |
- } catch (IOException e) { |
- throw new RuntimeException(e); |
- } |
- } |
- |
- /** |
- * Copy and upload {@param minidumps} by one array at a time - i.e. the minidumps in a single |
- * array in {@param minidumps} will all be copied in the same call into CrashReceiverService. |
- * @param fileManager the CrashFileManager to use when copying/renaming minidumps. |
- * @param minidumps an array of arrays of minidumps to copy and upload, by copying one array at |
- * a time. |
- * @param uids an array of uids declaring the uids used when calling into CrashReceiverService. |
- * @return the uploaded files. |
- */ |
- private File[] copyAndUploadMinidumpsSync(CrashFileManager fileManager, File[][] minidumps, |
- int[] uids) throws FileNotFoundException { |
- CrashReceiverService crashReceiverService = new CrashReceiverService(); |
- assertEquals(minidumps.length, uids.length); |
- // Ensure the upload service minidump directory is empty before we start copying files. |
- File[] initialMinidumps = |
- fileManager.getAllMinidumpFiles(MinidumpUploaderImpl.MAX_UPLOAD_TRIES_ALLOWED); |
- assertEquals(0, initialMinidumps.length); |
- |
- // Open file descriptors to the files and then delete the files. |
- ParcelFileDescriptor[][] fileDescriptors = new ParcelFileDescriptor[minidumps.length][]; |
- int numMinidumps = 0; |
- for (int n = 0; n < minidumps.length; n++) { |
- File[] currentMinidumps = minidumps[n]; |
- numMinidumps += currentMinidumps.length; |
- fileDescriptors[n] = new ParcelFileDescriptor[currentMinidumps.length]; |
- for (int m = 0; m < currentMinidumps.length; m++) { |
- fileDescriptors[n][m] = ParcelFileDescriptor.open( |
- currentMinidumps[m], ParcelFileDescriptor.MODE_READ_ONLY); |
- assertTrue(currentMinidumps[m].delete()); |
- } |
- crashReceiverService.performMinidumpCopyingSerially( |
- getInstrumentation().getTargetContext(), uids[n] /* uid */, fileDescriptors[n], |
- false /* scheduleUploads */); |
- } |
- |
- final CrashReportingPermissionManager permManager = |
- new MockCrashReportingPermissionManager() { |
- { mIsEnabledForTests = true; } |
- }; |
- MinidumpUploader minidumpUploader = |
- new TestMinidumpUploaderImpl(getInstrumentation().getTargetContext(), permManager, |
- false /* cleanOutMinidumps */); |
- |
- uploadMinidumpsSync(minidumpUploader, false /* expectReschedule */); |
- // Ensure there are no minidumps left to upload. |
- File[] nonUploadedMinidumps = |
- fileManager.getAllMinidumpFiles(MinidumpUploaderImpl.MAX_UPLOAD_TRIES_ALLOWED); |
- assertEquals(0, nonUploadedMinidumps.length); |
- |
- File[] uploadedFiles = fileManager.getAllUploadedFiles(); |
- assertEquals(numMinidumps, uploadedFiles.length); |
- return uploadedFiles; |
- } |
- |
- private File createMinidumpFileInCrashDir(String name) throws IOException { |
+ protected File createMinidumpFileInCrashDir(String name) throws IOException { |
File minidumpFile = new File(mCrashDir, name); |
setUpMinidumpFile(minidumpFile, BOUNDARY); |
return minidumpFile; |