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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.crash; 5 package org.chromium.chrome.browser.crash;
6 6
7 import android.annotation.TargetApi;
8 import android.app.job.JobInfo;
9 import android.app.job.JobScheduler;
7 import android.content.ComponentName; 10 import android.content.ComponentName;
8 import android.content.Context; 11 import android.content.Context;
9 import android.content.Intent; 12 import android.content.Intent;
13 import android.os.Build;
10 import android.support.test.filters.MediumTest; 14 import android.support.test.filters.MediumTest;
11 15
12 import org.chromium.base.StreamUtil; 16 import org.chromium.base.StreamUtil;
13 import org.chromium.base.test.util.AdvancedMockContext; 17 import org.chromium.base.test.util.AdvancedMockContext;
18 import org.chromium.chrome.browser.ChromeFeatureList;
19 import org.chromium.components.background_task_scheduler.TaskIds;
14 import org.chromium.components.minidump_uploader.CrashFileManager; 20 import org.chromium.components.minidump_uploader.CrashFileManager;
15 import org.chromium.components.minidump_uploader.CrashTestCase; 21 import org.chromium.components.minidump_uploader.CrashTestCase;
16 22
17 import java.io.BufferedReader; 23 import java.io.BufferedReader;
18 import java.io.File; 24 import java.io.File;
19 import java.io.FileReader; 25 import java.io.FileReader;
20 import java.io.FileWriter; 26 import java.io.FileWriter;
21 import java.io.IOException; 27 import java.io.IOException;
22 import java.util.ArrayList; 28 import java.util.Arrays;
29 import java.util.HashMap;
23 import java.util.List; 30 import java.util.List;
24 import java.util.concurrent.atomic.AtomicInteger; 31 import java.util.Map;
25 32
26 /** 33 /**
27 * Unittests for {@link LogcatExtractionRunnable}. 34 * Unittests for {@link LogcatExtractionRunnable}.
28 */ 35 */
29 public class LogcatExtractionRunnableTest extends CrashTestCase { 36 public class LogcatExtractionRunnableTest extends CrashTestCase {
30 private File mCrashDir; 37 private File mCrashDir;
31 38
39 private static final String BOUNDARY = "boundary";
40 private static final String MINIDUMP_CONTENTS = "important minidump contents ";
41 private static final List<String> LOGCAT =
42 Arrays.asList("some random log content", "some more deterministic lo g content");
43
44 private static class TestLogcatExtractionRunnable extends LogcatExtractionRu nnable {
45 TestLogcatExtractionRunnable(Context context, File minidump) {
46 super(context, minidump);
47 }
48
49 @Override
50 protected List<String> getLogcat() {
51 return LOGCAT;
52 }
53 };
54
55 @TargetApi(Build.VERSION_CODES.M)
56 private static class TestJobScheduler extends JobScheduler {
57 TestJobScheduler() {}
58
59 @Override
60 public void cancel(int jobId) {}
61
62 @Override
63 public void cancelAll() {}
64
65 @Override
66 public List<JobInfo> getAllPendingJobs() {
67 return null;
68 }
69
70 @Override
71 public JobInfo getPendingJob(int jobId) {
72 return null;
73 }
74
75 @Override
76 public int schedule(JobInfo job) {
77 assertEquals(TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID, job.getId());
78 assertEquals(ChromeMinidumpUploadJobService.class.getName(),
79 job.getService().getClassName());
80 return 0;
81 }
82 };
83
84 // Responsible for verifying that the correct intent is fired after the logc at is extracted.
85 private class TestContext extends AdvancedMockContext {
86 int mNumServiceStarts;
87
88 TestContext(Context realContext) {
89 super(realContext);
90 }
91
92 @Override
93 public ComponentName startService(Intent intent) {
94 assertFalse("Should only start a service directly when the job sched uler is disabled.",
95 ChromeFeatureList.isEnabled(
96 ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCH EDULER));
97 ++mNumServiceStarts;
98 assertEquals(1, mNumServiceStarts);
99 assertEquals(
100 MinidumpUploadService.class.getName(), intent.getComponent() .getClassName());
101 assertEquals(MinidumpUploadService.ACTION_UPLOAD, intent.getAction() );
102 assertEquals(new File(mCrashDir, "test.dmp.try0").getAbsolutePath(),
103 intent.getStringExtra(MinidumpUploadService.FILE_TO_UPLOAD_K EY));
104 return super.startService(intent);
105 }
106
107 @Override
108 public Object getSystemService(String name) {
109 if (Context.JOB_SCHEDULER_SERVICE.equals(name)) {
110 assertTrue("Should only access the JobScheduler when it is enabl ed.",
111 ChromeFeatureList.isEnabled(
112 ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB _SCHEDULER));
113 return new TestJobScheduler();
114 }
115
116 return super.getSystemService(name);
117 }
118 };
119
32 @Override 120 @Override
33 protected void setUp() throws Exception { 121 protected void setUp() throws Exception {
34 super.setUp(); 122 super.setUp();
35 mCrashDir = new CrashFileManager(mCacheDir).getCrashDirectory(); 123 mCrashDir = new CrashFileManager(mCacheDir).getCrashDirectory();
36 } 124 }
37 125
38 @MediumTest 126 @Override
39 public void testSimpleExtraction() { 127 protected void tearDown() throws Exception {
40 // Set up the test. 128 ChromeFeatureList.setTestFeatures(null);
41 final List<String> logcat = new ArrayList<String>(); 129 super.tearDown();
42 logcat.add("some random log content"); 130 }
43 logcat.add("some more deterministic log content");
44 131
45 final File minidump = new File(mCrashDir, "test.dmp"); 132 /**
46 final String boundary = "boundary"; 133 * Sets whether to upload minidumps using the JobScheduler API. Minidumps ca n either be uploaded
47 final String minidumpContents = "important minidump contents"; 134 * via a JobScheduler, or via a direct Intent service.
135 * @param enable Whether to enable the JobScheduler API.
136 */
137 private void setJobSchedulerEnabled(boolean enable) {
138 Map<String, Boolean> features = new HashMap<>();
139 features.put(ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCHEDULER, enable);
140 ChromeFeatureList.setTestFeatures(features);
141 }
142
143 /**
144 * Creates a simple fake minidump file for testing.
145 * @param filename The name of the file to create.
146 */
147 private File createMinidump(String filename) throws IOException {
148 File minidump = new File(mCrashDir, filename);
48 FileWriter writer = null; 149 FileWriter writer = null;
49 try { 150 try {
50 writer = new FileWriter(minidump); 151 writer = new FileWriter(minidump);
51 writer.write(boundary + "\n"); 152 writer.write(BOUNDARY + "\n");
52 writer.write(minidumpContents + "\n"); 153 writer.write(MINIDUMP_CONTENTS + "\n");
53 } catch (IOException e) {
54 fail(e.toString());
55 } finally { 154 } finally {
56 StreamUtil.closeQuietly(writer); 155 StreamUtil.closeQuietly(writer);
57 } 156 }
157 return minidump;
158 }
58 159
59 // The testContext is responsible for verifying that the correct intent is fired after the 160 /**
60 // logcat is extracted. 161 * Verifies that the contents of the {@param filename} are the expected ones .
61 final AtomicInteger numServiceStarts = new AtomicInteger(0); 162 * @param filename The name of the file containing the concatenated logcat a nd minidump output.
62 Context testContext = new AdvancedMockContext(getInstrumentation().getTa rgetContext()) { 163 */
63 @Override 164 private void verifyMinidumpWithLogcat(String filename) throws IOException {
64 public ComponentName startService(Intent intent) {
65 assertEquals(1, numServiceStarts.incrementAndGet());
66 assertEquals(MinidumpUploadService.class.getName(),
67 intent.getComponent().getClassName());
68 assertEquals(MinidumpUploadService.ACTION_UPLOAD, intent.getActi on());
69 assertEquals(new File(mCrashDir, "test.dmp.try0").getAbsolutePat h(),
70 intent.getStringExtra(MinidumpUploadService.FILE_TO_UPLO AD_KEY));
71 return super.startService(intent);
72 }
73 };
74
75 // Extract the logcat!
76 LogcatExtractionRunnable runnable = new LogcatExtractionRunnable(testCon text, minidump) {
77 @Override
78 protected List<String> getLogcat() {
79 return logcat;
80 }
81 };
82 runnable.run();
83
84 // Verify the file contents.
85 BufferedReader input = null; 165 BufferedReader input = null;
86 try { 166 try {
87 File logfile = new File(mCrashDir, "test.dmp.try0"); 167 File minidumpWithLogcat = new File(mCrashDir, filename);
88 assertTrue("Logfile should exist!", logfile.exists()); 168 assertTrue("Should have created a file containing the logcat and min idump contents",
169 minidumpWithLogcat.exists());
89 170
90 input = new BufferedReader(new FileReader(logfile)); 171 input = new BufferedReader(new FileReader(minidumpWithLogcat));
91 assertEquals("The first line should be the boundary line.", boundary , input.readLine()); 172 assertEquals("The first line should be the boundary line.", BOUNDARY , input.readLine());
92 assertEquals("The second line should be the content dispoistion.", 173 assertEquals("The second line should be the content dispoistion.",
93 MinidumpLogcatPrepender.LOGCAT_CONTENT_DISPOSITION, input.re adLine()); 174 MinidumpLogcatPrepender.LOGCAT_CONTENT_DISPOSITION, input.re adLine());
94 assertEquals("The third line should be the content type.", 175 assertEquals("The third line should be the content type.",
95 MinidumpLogcatPrepender.LOGCAT_CONTENT_TYPE, input.readLine( )); 176 MinidumpLogcatPrepender.LOGCAT_CONTENT_TYPE, input.readLine( ));
96 assertEquals("The fourth line should be blank, for padding.", "", in put.readLine()); 177 assertEquals("The fourth line should be blank, for padding.", "", in put.readLine());
97 for (String expected : logcat) { 178 for (String expected : LOGCAT) {
98 assertEquals(expected, input.readLine()); 179 assertEquals("The logcat contents should match", expected, input .readLine());
99 } 180 }
100 assertEquals("The logcat should be followed by the boundary line.", boundary, 181 assertEquals("The logcat should be followed by the boundary line.", BOUNDARY,
101 input.readLine()); 182 input.readLine());
102 assertEquals( 183 assertEquals(
103 "The minidump contents should follow.", minidumpContents, in put.readLine()); 184 "The minidump contents should follow.", MINIDUMP_CONTENTS, i nput.readLine());
104 assertNull("There should be nothing else in the file", input.readLin e()); 185 assertNull("There should be nothing else in the file", input.readLin e());
105 } catch (IOException e) {
106 fail(e.toString());
107 } finally { 186 } finally {
108 StreamUtil.closeQuietly(input); 187 StreamUtil.closeQuietly(input);
109 } 188 }
110 } 189 }
190
191 @MediumTest
192 public void testSimpleExtraction_SansJobScheduler() throws IOException {
193 setJobSchedulerEnabled(false);
194 final File minidump = createMinidump("test.dmp");
195 Context testContext = new TestContext(getInstrumentation().getTargetCont ext());
196
197 LogcatExtractionRunnable runnable = new TestLogcatExtractionRunnable(tes tContext, minidump);
198 runnable.run();
199
200 verifyMinidumpWithLogcat("test.dmp.try0");
201 }
202
203 @MediumTest
204 public void testSimpleExtraction_WithJobScheduler() throws IOException {
205 // The JobScheduler API is only available as of Android M.
206 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
207
208 setJobSchedulerEnabled(true);
209 final File minidump = createMinidump("test.dmp");
210 Context testContext = new TestContext(getInstrumentation().getTargetCont ext());
211
212 LogcatExtractionRunnable runnable = new TestLogcatExtractionRunnable(tes tContext, minidump);
213 runnable.run();
214
215 verifyMinidumpWithLogcat("test.dmp.try0");
216 }
111 } 217 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698