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

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

Issue 2737263006: [Android Crash Reporting] Allow uploading minidumps via the JobScheduler (Closed)
Patch Set: Assert that job scheduled successfully Created 3 years, 9 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/LogcatExtractionRunnableTest.java
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java
index cd851953dff3bf5634e50b2c5a3716357c21a30d..727ce4987d8df4a53d460539b8fcf7dea50a402d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/crash/LogcatExtractionRunnableTest.java
@@ -4,13 +4,19 @@
package org.chromium.chrome.browser.crash;
+import android.annotation.TargetApi;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.os.Build;
import android.support.test.filters.MediumTest;
import org.chromium.base.StreamUtil;
import org.chromium.base.test.util.AdvancedMockContext;
+import org.chromium.chrome.browser.ChromeFeatureList;
+import org.chromium.components.background_task_scheduler.TaskIds;
import org.chromium.components.minidump_uploader.CrashFileManager;
import org.chromium.components.minidump_uploader.CrashTestCase;
@@ -19,9 +25,10 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Map;
/**
* Unittests for {@link LogcatExtractionRunnable}.
@@ -29,83 +36,182 @@ import java.util.concurrent.atomic.AtomicInteger;
public class LogcatExtractionRunnableTest extends CrashTestCase {
private File mCrashDir;
+ private static final String BOUNDARY = "boundary";
+ private static final String MINIDUMP_CONTENTS = "important minidump contents";
+ private static final List<String> LOGCAT =
+ Arrays.asList("some random log content", "some more deterministic log content");
+
+ private static class TestLogcatExtractionRunnable extends LogcatExtractionRunnable {
+ TestLogcatExtractionRunnable(Context context, File minidump) {
+ super(context, minidump);
+ }
+
+ @Override
+ protected List<String> getLogcat() {
+ return LOGCAT;
+ }
+ };
+
+ @TargetApi(Build.VERSION_CODES.M)
+ private static class TestJobScheduler extends JobScheduler {
+ TestJobScheduler() {}
+
+ @Override
+ public void cancel(int jobId) {}
+
+ @Override
+ public void cancelAll() {}
+
+ @Override
+ public List<JobInfo> getAllPendingJobs() {
+ return null;
+ }
+
+ @Override
+ public JobInfo getPendingJob(int jobId) {
+ return null;
+ }
+
+ @Override
+ public int schedule(JobInfo job) {
+ assertEquals(TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID, job.getId());
+ assertEquals(ChromeMinidumpUploadJobService.class.getName(),
+ job.getService().getClassName());
+ return 0;
+ }
+ };
+
+ // Responsible for verifying that the correct intent is fired after the logcat is extracted.
+ private class TestContext extends AdvancedMockContext {
+ int mNumServiceStarts;
+
+ TestContext(Context realContext) {
+ super(realContext);
+ }
+
+ @Override
+ public ComponentName startService(Intent intent) {
+ assertFalse("Should only start a service directly when the job scheduler is disabled.",
+ ChromeFeatureList.isEnabled(
+ ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCHEDULER));
+ ++mNumServiceStarts;
+ assertEquals(1, mNumServiceStarts);
+ assertEquals(
+ MinidumpUploadService.class.getName(), intent.getComponent().getClassName());
+ assertEquals(MinidumpUploadService.ACTION_UPLOAD, intent.getAction());
+ assertEquals(new File(mCrashDir, "test.dmp.try0").getAbsolutePath(),
+ intent.getStringExtra(MinidumpUploadService.FILE_TO_UPLOAD_KEY));
+ return super.startService(intent);
+ }
+
+ @Override
+ public Object getSystemService(String name) {
+ if (Context.JOB_SCHEDULER_SERVICE.equals(name)) {
+ assertTrue("Should only access the JobScheduler when it is enabled.",
+ ChromeFeatureList.isEnabled(
+ ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCHEDULER));
+ return new TestJobScheduler();
+ }
+
+ return super.getSystemService(name);
+ }
+ };
+
@Override
protected void setUp() throws Exception {
super.setUp();
mCrashDir = new CrashFileManager(mCacheDir).getCrashDirectory();
}
- @MediumTest
- public void testSimpleExtraction() {
- // Set up the test.
- final List<String> logcat = new ArrayList<String>();
- logcat.add("some random log content");
- logcat.add("some more deterministic log content");
-
- final File minidump = new File(mCrashDir, "test.dmp");
- final String boundary = "boundary";
- final String minidumpContents = "important minidump contents";
+ @Override
+ protected void tearDown() throws Exception {
+ ChromeFeatureList.setTestFeatures(null);
+ super.tearDown();
+ }
+
+ /**
+ * Sets whether to upload minidumps using the JobScheduler API. Minidumps can either be uploaded
+ * via a JobScheduler, or via a direct Intent service.
+ * @param enable Whether to enable the JobScheduler API.
+ */
+ private void setJobSchedulerEnabled(boolean enable) {
+ Map<String, Boolean> features = new HashMap<>();
+ features.put(ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCHEDULER, enable);
+ ChromeFeatureList.setTestFeatures(features);
+ }
+
+ /**
+ * Creates a simple fake minidump file for testing.
+ * @param filename The name of the file to create.
+ */
+ private File createMinidump(String filename) throws IOException {
+ File minidump = new File(mCrashDir, filename);
FileWriter writer = null;
try {
writer = new FileWriter(minidump);
- writer.write(boundary + "\n");
- writer.write(minidumpContents + "\n");
- } catch (IOException e) {
- fail(e.toString());
+ writer.write(BOUNDARY + "\n");
+ writer.write(MINIDUMP_CONTENTS + "\n");
} finally {
StreamUtil.closeQuietly(writer);
}
+ return minidump;
+ }
- // The testContext is responsible for verifying that the correct intent is fired after the
- // logcat is extracted.
- final AtomicInteger numServiceStarts = new AtomicInteger(0);
- Context testContext = new AdvancedMockContext(getInstrumentation().getTargetContext()) {
- @Override
- public ComponentName startService(Intent intent) {
- assertEquals(1, numServiceStarts.incrementAndGet());
- assertEquals(MinidumpUploadService.class.getName(),
- intent.getComponent().getClassName());
- assertEquals(MinidumpUploadService.ACTION_UPLOAD, intent.getAction());
- assertEquals(new File(mCrashDir, "test.dmp.try0").getAbsolutePath(),
- intent.getStringExtra(MinidumpUploadService.FILE_TO_UPLOAD_KEY));
- return super.startService(intent);
- }
- };
-
- // Extract the logcat!
- LogcatExtractionRunnable runnable = new LogcatExtractionRunnable(testContext, minidump) {
- @Override
- protected List<String> getLogcat() {
- return logcat;
- }
- };
- runnable.run();
-
- // Verify the file contents.
+ /**
+ * Verifies that the contents of the {@param filename} are the expected ones.
+ * @param filename The name of the file containing the concatenated logcat and minidump output.
+ */
+ private void verifyMinidumpWithLogcat(String filename) throws IOException {
BufferedReader input = null;
try {
- File logfile = new File(mCrashDir, "test.dmp.try0");
- assertTrue("Logfile should exist!", logfile.exists());
+ File minidumpWithLogcat = new File(mCrashDir, filename);
+ assertTrue("Should have created a file containing the logcat and minidump contents",
+ minidumpWithLogcat.exists());
- input = new BufferedReader(new FileReader(logfile));
- assertEquals("The first line should be the boundary line.", boundary, input.readLine());
+ input = new BufferedReader(new FileReader(minidumpWithLogcat));
+ assertEquals("The first line should be the boundary line.", BOUNDARY, input.readLine());
assertEquals("The second line should be the content dispoistion.",
MinidumpLogcatPrepender.LOGCAT_CONTENT_DISPOSITION, input.readLine());
assertEquals("The third line should be the content type.",
MinidumpLogcatPrepender.LOGCAT_CONTENT_TYPE, input.readLine());
assertEquals("The fourth line should be blank, for padding.", "", input.readLine());
- for (String expected : logcat) {
- assertEquals(expected, input.readLine());
+ for (String expected : LOGCAT) {
+ assertEquals("The logcat contents should match", expected, input.readLine());
}
- assertEquals("The logcat should be followed by the boundary line.", boundary,
+ assertEquals("The logcat should be followed by the boundary line.", BOUNDARY,
input.readLine());
assertEquals(
- "The minidump contents should follow.", minidumpContents, input.readLine());
+ "The minidump contents should follow.", MINIDUMP_CONTENTS, input.readLine());
assertNull("There should be nothing else in the file", input.readLine());
- } catch (IOException e) {
- fail(e.toString());
} finally {
StreamUtil.closeQuietly(input);
}
}
+
+ @MediumTest
+ public void testSimpleExtraction_SansJobScheduler() throws IOException {
+ setJobSchedulerEnabled(false);
+ final File minidump = createMinidump("test.dmp");
+ Context testContext = new TestContext(getInstrumentation().getTargetContext());
+
+ LogcatExtractionRunnable runnable = new TestLogcatExtractionRunnable(testContext, minidump);
+ runnable.run();
+
+ verifyMinidumpWithLogcat("test.dmp.try0");
+ }
+
+ @MediumTest
+ public void testSimpleExtraction_WithJobScheduler() throws IOException {
+ // The JobScheduler API is only available as of Android M.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
+
+ setJobSchedulerEnabled(true);
+ final File minidump = createMinidump("test.dmp");
+ Context testContext = new TestContext(getInstrumentation().getTargetContext());
+
+ LogcatExtractionRunnable runnable = new TestLogcatExtractionRunnable(testContext, minidump);
+ runnable.run();
+
+ verifyMinidumpWithLogcat("test.dmp.try0");
+ }
}

Powered by Google App Engine
This is Rietveld 408576698