Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3624)

Unified Diff: chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a55bbe8fad72e714653c09fce3f6707753947ae
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/MinidumpUploadServiceTest.java
@@ -0,0 +1,395 @@
+// 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 android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.base.test.util.AdvancedMockContext;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.net.NetworkChangeNotifier;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Testcase for {@link MinidumpUploadService}.
+ */
+public class MinidumpUploadServiceTest extends CrashTestCase {
+
+ private static final int CHECK_INTERVAL_MS = 250;
+ private static final int MAX_TIMEOUT_MS = 20000;
+ private static final String BOUNDARY = "TESTBOUNDARY";
+
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testFindAndUploadLastCrash() throws IOException {
+ // Setup prerequisites.
+ final AtomicInteger numServiceStarts = new AtomicInteger(0);
+ final File minidumpFile = new File(mCrashDir, "chromium_renderer-123.dmp");
+ MinidumpPreparationContext context = new MinidumpPreparationContext(
+ getInstrumentation().getTargetContext()) {
+ @Override
+ public ComponentName startService(Intent intentToCheck) {
+ String filePath =
+ intentToCheck.getStringExtra(MinidumpUploadService.FILE_TO_UPLOAD_KEY);
+ assertEquals("Minidump path should be the absolute path",
+ minidumpFile.getAbsolutePath(), filePath);
+ assertEquals("Should only call service once", 1,
+ numServiceStarts.incrementAndGet());
+ assertEquals("Action should be correct",
+ MinidumpUploadService.ACTION_UPLOAD, intentToCheck.getAction());
+ return new ComponentName(getPackageName(), MinidumpUploadService.class.getName());
+ }
+
+ };
+ MinidumpUploadService service = new TestMinidumpUploadService(context);
+ setUpMinidumpFile(minidumpFile, BOUNDARY);
+
+ // Run test.
+ Intent findAndUploadLastCrashIntent =
+ MinidumpUploadService.createFindAndUploadLastCrashIntent(context);
+ service.onCreate();
+ service.onHandleIntent(findAndUploadLastCrashIntent);
+
+ // Verify.
+ assertTrue("Minidump file should exist", minidumpFile.isFile());
+ assertEquals("Should have called startService() once", 1, numServiceStarts.intValue());
+ }
+
+ private static class TestMinidumpUploadService extends MinidumpUploadService {
+ private TestMinidumpUploadService() {}
+ private TestMinidumpUploadService(Context context) {
+ attachBaseContext(context);
+ }
+
+ private void attachBaseContextLate(Context base) {
+ super.attachBaseContext(base);
+ }
+ }
+
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testFindAndUploadLastCrashNoFile() {
+ // Setup prerequisites.
+ MinidumpPreparationContext context = new MinidumpPreparationContext(
+ getInstrumentation().getTargetContext()) {
+ @Override
+ public ComponentName startService(Intent intentToCheck) {
+ fail("Should not start service");
+ return new ComponentName(getPackageName(), MinidumpUploadService.class.getName());
+ }
+
+ };
+ MinidumpUploadService service = new TestMinidumpUploadService(context);
+
+ // Run test.
+ Intent findAndUploadLastCrashIntent =
+ MinidumpUploadService.createFindAndUploadLastCrashIntent(context);
+ service.onCreate();
+ service.onHandleIntent(findAndUploadLastCrashIntent);
+
+ // Verification is done by the test NOT failing with fail(...) in the
+ // MinidumpPreparationContext startService(...) method.
+ }
+
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testFindAndUploadAllCrashes() throws IOException {
+ // Setup prerequisites.
+ final AtomicInteger numServiceStarts = new AtomicInteger(0);
+ final File[] minidumpFiles = {
+ new File(mCrashDir, "chromium_renderer-111.dmp1"),
+ new File(mCrashDir, "chromium_renderer-222.dmp2"),
+ new File(mCrashDir, "chromium_renderer-333.dmp3"),
+ };
+ MinidumpPreparationContext context = new MinidumpPreparationContext(
+ getInstrumentation().getTargetContext()) {
+ @Override
+ public ComponentName startService(Intent intentToCheck) {
+ String filePath =
+ intentToCheck.getStringExtra(MinidumpUploadService.FILE_TO_UPLOAD_KEY);
+ // Assuming numServicesStart value corresponds to minidumpFiles index.
+ assertEquals("Minidump path should be the absolute path",
+ minidumpFiles[numServiceStarts.intValue()].getAbsolutePath(), filePath);
+ assertTrue("Should not call service more than number of files",
+ numServiceStarts.incrementAndGet() <= minidumpFiles.length);
+ assertEquals("Action should be correct",
+ MinidumpUploadService.ACTION_UPLOAD, intentToCheck.getAction());
+ return new ComponentName(getPackageName(), MinidumpUploadService.class.getName());
+ }
+
+ };
+ MinidumpUploadService service = new TestMinidumpUploadService(context);
+ for (File minidumpFile : minidumpFiles) {
+ setUpMinidumpFile(minidumpFile, BOUNDARY);
+ }
+
+ // Run test.
+ Intent findAndUploadAllCrashesIntent =
+ MinidumpUploadService.createFindAndUploadAllCrashesIntent(context);
+ service.onCreate();
+ service.onHandleIntent(findAndUploadAllCrashesIntent);
+
+ // Verify.
+ for (File minidumpFile : minidumpFiles) {
+ assertTrue("Minidump file should exist: " + minidumpFile, minidumpFile.isFile());
+ }
+ assertEquals("Should have called startService() same number of times as there are files",
+ minidumpFiles.length, numServiceStarts.intValue());
+ }
+
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testUploadCrash() throws IOException, InterruptedException {
+ List<CountedMinidumpUploadCallable> callables =
+ new ArrayList<CountedMinidumpUploadCallable>();
+ callables.add(new CountedMinidumpUploadCallable(
+ "chromium_renderer-111.dmp1", true, false));
+ runUploadCrashTest(callables);
+ }
+
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testUploadCrashWithThreeFails() throws IOException, InterruptedException {
+ // Create |MAX_TRIES_ALLOWED| callables.
+ final List<CountedMinidumpUploadCallable> callables =
+ new ArrayList<CountedMinidumpUploadCallable>();
+ for (int i = 0; i < MinidumpUploadService.MAX_TRIES_ALLOWED; i++) {
+ callables.add(new CountedMinidumpUploadCallable(
+ "chromium_renderer-111.dmp1" + (i > 0 ? ".try" + i : "") , false, true));
+ }
+ runUploadCrashTest(callables);
+ }
+
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testUploadCrashWithOneFailWithNetwork() throws IOException, InterruptedException {
+ List<CountedMinidumpUploadCallable> callables =
+ new ArrayList<CountedMinidumpUploadCallable>();
+ callables.add(new CountedMinidumpUploadCallable(
+ "chromium_renderer-111.dmp1", false, true));
+ callables.add(new CountedMinidumpUploadCallable(
+ "chromium_renderer-111.dmp1.try1", true, true));
+ runUploadCrashTest(callables);
+ }
+
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testUploadCrashWithOneFailNoNetwork() throws IOException, InterruptedException {
+ List<CountedMinidumpUploadCallable> callables =
+ new ArrayList<CountedMinidumpUploadCallable>();
+ callables.add(new CountedMinidumpUploadCallable(
+ "chromium_renderer-111.dmp1", false, false));
+ runUploadCrashTest(callables);
+ }
+
+ @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
+ private void runUploadCrashTest(final List<CountedMinidumpUploadCallable> callables)
+ throws IOException, InterruptedException {
+ // Setup prerequisites.
+ // This version of the service overrides the createMinidumpUploadCallable(...) to be able
+ // to return fake ones. It also ensures that the service never tries to create a callable
+ // too many times.
+ TestMinidumpUploadService service = new TestMinidumpUploadService() {
+ int mIndex = 0;
+ boolean mTriggerNetworkChange = false;
+
+ @Override
+ MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFile, File logfile) {
+ if (mIndex >= callables.size()) {
+ fail("Should not create callable number " + mIndex);
+ }
+ CountedMinidumpUploadCallable callable = callables.get(mIndex++);
+ if (callable.mTriggerNetworkChange) {
+ mTriggerNetworkChange = true;
+ }
+ return callable;
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ try {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // Set up basically a fake.
+ if (!NetworkChangeNotifier.isInitialized()) {
+ NetworkChangeNotifier.init(getApplicationContext());
+ }
+ }
+ });
+ } catch (Throwable t) {
+ t.printStackTrace();
+ fail("Failed to set up NetworkChangeNotifier");
+ }
+
+ super.onHandleIntent(intent);
+
+ if (mTriggerNetworkChange) {
+ mTriggerNetworkChange = false;
+ try {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ NetworkChangeNotifier.setAutoDetectConnectivityState(false);
+ // Quickly force the state to be connected and back to disconnected.
+ // An event should be triggered for retry logics.
+ NetworkChangeNotifier.forceConnectivityState(false);
+ NetworkChangeNotifier.forceConnectivityState(true);
+ }
+ });
+ } catch (Throwable t) {
+ t.printStackTrace();
+ fail("Failed to trigger NetworkChangeNotifier");
+ }
+ }
+ }
+ };
+ // Create a context that supports call to startService(...), where it runs the new service
+ // calls on a handler thread. We pass in the MinidumpUploadService as an argument so we
+ // can call it directly without going through the Android framework.
+ final MinidumpPreparationContext context = new MinidumpPreparationContext(
+ getInstrumentation().getTargetContext(), service) {
+ Handler mHandler;
+ {
+ HandlerThread handlerThread =
+ new HandlerThread("MinidumpUploadServiceTest Handler Thread");
+ handlerThread.start();
+ mHandler = new Handler(handlerThread.getLooper());
+ }
+
+ @Override
+ public ComponentName startService(final Intent intentToCheck) {
+ assertTrue(MinidumpUploadService.ACTION_UPLOAD.equals(intentToCheck.getAction())
+ || MinidumpUploadService.ACTION_FIND_ALL.equals(intentToCheck.getAction()));
+ // Post to the handler thread to run the retry intent.
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mService.onHandleIntent(intentToCheck);
+ }
+ });
+ return new ComponentName(getPackageName(), MinidumpUploadService.class.getName());
+ }
+
+ };
+ // We need the context before we can attach it to the service, so since Context is
+ // dependent on the service, we do this after context creation.
+ service.attachBaseContextLate(context);
+ // Create the file used for uploading.
+ File minidumpFile = new File(mCrashDir, "chromium_renderer-111.dmp1");
+ minidumpFile.createNewFile();
+ File logfile = new File(mCacheDir, CrashFileManager.CRASH_DUMP_LOGFILE);
+ setUpMinidumpFile(minidumpFile, BOUNDARY);
+
+ // Run test.
+ Intent uploadIntent =
+ MinidumpUploadService.createUploadIntent(context, minidumpFile, logfile);
+ service.onCreate();
+ service.onHandleIntent(uploadIntent);
+
+ // Verify asynchronously.
+ assertTrue("All callables should have a call-count of 1",
+ CriteriaHelper.pollForCriteria(new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ for (CountedMinidumpUploadCallable callable : callables) {
+ if (callable.mCalledCount != 1) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }, MAX_TIMEOUT_MS, CHECK_INTERVAL_MS));
+ }
+
+ /**
+ * This tests how we instantiate crash uploading from Main, so it is just a sanity check.
+ */
+ @SmallTest
+ @Feature({"Android-AppBase"})
+ public void testTryUploadAllCrashDumpsHelperMethod() {
+ // Setup prerequisites.
+ final String startServiceFlag = "startServiceFlag";
+ MinidumpPreparationContext context = new MinidumpPreparationContext(
+ getInstrumentation().getTargetContext()) {
+ @Override
+ public ComponentName startService(Intent intentToCheck) {
+ assertEquals(MinidumpUploadService.ACTION_FIND_ALL, intentToCheck.getAction());
+ setFlag(startServiceFlag);
+ return new ComponentName(getPackageName(), MinidumpUploadService.class.getName());
+ }
+ };
+
+ // Run test.
+ MinidumpUploadService.tryUploadAllCrashDumps(context);
+
+ // Verify.
+ assertTrue("Should have called startService(...)", context.isFlagSet(startServiceFlag));
+ }
+
+ private class MinidumpPreparationContext extends AdvancedMockContext {
+ /**
+ * Field used in overridden versions of startService() so we can support retries.
+ */
+ protected MinidumpUploadService mService;
+
+ public MinidumpPreparationContext(Context targetContext) {
+ this(targetContext, null);
+ }
+
+ public MinidumpPreparationContext(Context targetContext, MinidumpUploadService service) {
+ super(targetContext);
+ mService = service;
+ }
+
+ @Override
+ public File getCacheDir() {
+ return mCacheDir;
+ }
+ }
+
+ /**
+ * A fake callable, that just counts the number of times it is called.
+ *
+ * It can be constructed with the wanted return-value of the call()-method.
+ */
+ private static class CountedMinidumpUploadCallable extends MinidumpUploadCallable {
+ private int mCalledCount;
+ private final boolean mResult;
+ private final boolean mTriggerNetworkChange;
+
+ /**
+ * Creates a fake callable, that just counts the number of times it is called.
+ *
+ * @param result the value to return from the call()-method.
+ * @param networkChange Should trigger a network change after this callable is finished.
+ * This essentially triggers a retry if result is set to fail.
+ */
+ private CountedMinidumpUploadCallable(
+ String fileName, boolean result, boolean networkChange) {
+ super(new File(fileName), null, null, null, null);
+ this.mResult = result;
+ this.mTriggerNetworkChange = networkChange;
+ }
+
+ @Override
+ public Boolean call() {
+ ++mCalledCount;
+ return mResult;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698