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

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: MinidumpUploadService tests 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.LOLLIPOP)
56 private static class TestJobScheduler extends JobScheduler {
57 private final JobScheduler mRealScheduler;
gsennton 2017/03/15 12:57:43 I don't quite see why you have a real JobScheduler
Ilya Sherman 2017/03/16 01:36:57 Hmm, good point. Simplified.
58
59 TestJobScheduler(JobScheduler realScheduler) {
60 mRealScheduler = realScheduler;
61 }
62
63 @Override
64 public void cancel(int jobId) {
65 mRealScheduler.cancel(jobId);
66 }
67
68 @Override
69 public void cancelAll() {
70 mRealScheduler.cancelAll();
71 }
72
73 @Override
74 public List<JobInfo> getAllPendingJobs() {
75 return mRealScheduler.getAllPendingJobs();
76 }
77
78 @Override
79 public JobInfo getPendingJob(int jobId) {
80 return mRealScheduler.getPendingJob(jobId);
81 }
82
83 @Override
84 public int schedule(JobInfo job) {
85 assertEquals(TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID, job.getId());
86 assertEquals(ChromeMinidumpUploadJobService.class.getName(),
87 job.getService().getClassName());
88 return mRealScheduler.schedule(job);
89 }
90 };
91
92 // Responsible for verifying that the correct intent is fired after the logc at is extracted.
93 private class TestContext extends AdvancedMockContext {
94 int mNumServiceStarts;
95
96 TestContext(Context realContext) {
97 super(realContext);
98 }
99
100 @Override
101 public ComponentName startService(Intent intent) {
102 assertFalse("Should only start a service directly when the job sched uler is disabled.",
103 ChromeFeatureList.isEnabled(
104 ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCH EDULER));
105 ++mNumServiceStarts;
106 assertEquals(1, mNumServiceStarts);
107 assertEquals(
108 MinidumpUploadService.class.getName(), intent.getComponent() .getClassName());
109 assertEquals(MinidumpUploadService.ACTION_UPLOAD, intent.getAction() );
110 assertEquals(new File(mCrashDir, "test.dmp.try0").getAbsolutePath(),
111 intent.getStringExtra(MinidumpUploadService.FILE_TO_UPLOAD_K EY));
112 return super.startService(intent);
113 }
114
115 @Override
116 public Object getSystemService(String name) {
117 if (Context.JOB_SCHEDULER_SERVICE.equals(name)) {
118 assertTrue("Should only access the JobScheduler when it is enabl ed.",
119 ChromeFeatureList.isEnabled(
120 ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB _SCHEDULER));
121 return new TestJobScheduler((JobScheduler) super.getSystemServic e(name));
122 }
123
124 return super.getSystemService(name);
125 }
126 };
127
32 @Override 128 @Override
33 protected void setUp() throws Exception { 129 protected void setUp() throws Exception {
34 super.setUp(); 130 super.setUp();
35 mCrashDir = new CrashFileManager(mCacheDir).getCrashDirectory(); 131 mCrashDir = new CrashFileManager(mCacheDir).getCrashDirectory();
36 } 132 }
37 133
38 @MediumTest 134 @Override
39 public void testSimpleExtraction() { 135 protected void tearDown() {
40 // Set up the test. 136 ChromeFeatureList.setTestFeatures(null);
41 final List<String> logcat = new ArrayList<String>(); 137 }
42 logcat.add("some random log content");
43 logcat.add("some more deterministic log content");
44 138
45 final File minidump = new File(mCrashDir, "test.dmp"); 139 /**
46 final String boundary = "boundary"; 140 * Sets whether to upload minidumps using the JobScheduler API. Minidumps ca n either be uploaded
47 final String minidumpContents = "important minidump contents"; 141 * via a JobScheduler, or via a direct Intent service.
142 * @param enable Whether to enable the JobScheduler API.
143 */
144 private void setJobSchedulerEnabled(boolean enable) {
145 Map<String, Boolean> features = new HashMap<>();
146 features.put(ChromeFeatureList.UPLOAD_CRASH_REPORTS_USING_JOB_SCHEDULER, enable);
147 ChromeFeatureList.setTestFeatures(features);
148 }
149
150 /**
151 * Creates a simple fake minidump file for testing.
152 * @param filename The name of the file to create.
153 */
154 private File createMinidump(String filename) throws IOException {
155 File minidump = new File(mCrashDir, filename);
48 FileWriter writer = null; 156 FileWriter writer = null;
49 try { 157 try {
50 writer = new FileWriter(minidump); 158 writer = new FileWriter(minidump);
51 writer.write(boundary + "\n"); 159 writer.write(BOUNDARY + "\n");
52 writer.write(minidumpContents + "\n"); 160 writer.write(MINIDUMP_CONTENTS + "\n");
53 } catch (IOException e) {
54 fail(e.toString());
55 } finally { 161 } finally {
56 StreamUtil.closeQuietly(writer); 162 StreamUtil.closeQuietly(writer);
57 } 163 }
164 return minidump;
165 }
58 166
59 // The testContext is responsible for verifying that the correct intent is fired after the 167 /**
60 // logcat is extracted. 168 * Verifies that the contents of the {@param filename} are the expected ones .
61 final AtomicInteger numServiceStarts = new AtomicInteger(0); 169 * @param filename The name of the file containing the concatenated logcat a nd minidump output.
62 Context testContext = new AdvancedMockContext(getInstrumentation().getTa rgetContext()) { 170 */
63 @Override 171 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; 172 BufferedReader input = null;
86 try { 173 try {
87 File logfile = new File(mCrashDir, "test.dmp.try0"); 174 File minidumpWithLogcat = new File(mCrashDir, filename);
88 assertTrue("Logfile should exist!", logfile.exists()); 175 assertTrue("Should have created a file containing the logcat and min idump contents",
176 minidumpWithLogcat.exists());
89 177
90 input = new BufferedReader(new FileReader(logfile)); 178 input = new BufferedReader(new FileReader(minidumpWithLogcat));
91 assertEquals("The first line should be the boundary line.", boundary , input.readLine()); 179 assertEquals("The first line should be the boundary line.", BOUNDARY , input.readLine());
92 assertEquals("The second line should be the content dispoistion.", 180 assertEquals("The second line should be the content dispoistion.",
93 MinidumpLogcatPrepender.LOGCAT_CONTENT_DISPOSITION, input.re adLine()); 181 MinidumpLogcatPrepender.LOGCAT_CONTENT_DISPOSITION, input.re adLine());
94 assertEquals("The third line should be the content type.", 182 assertEquals("The third line should be the content type.",
95 MinidumpLogcatPrepender.LOGCAT_CONTENT_TYPE, input.readLine( )); 183 MinidumpLogcatPrepender.LOGCAT_CONTENT_TYPE, input.readLine( ));
96 assertEquals("The fourth line should be blank, for padding.", "", in put.readLine()); 184 assertEquals("The fourth line should be blank, for padding.", "", in put.readLine());
97 for (String expected : logcat) { 185 for (String expected : LOGCAT) {
98 assertEquals(expected, input.readLine()); 186 assertEquals("The logcat contents should match", expected, input .readLine());
99 } 187 }
100 assertEquals("The logcat should be followed by the boundary line.", boundary, 188 assertEquals("The logcat should be followed by the boundary line.", BOUNDARY,
101 input.readLine()); 189 input.readLine());
102 assertEquals( 190 assertEquals(
103 "The minidump contents should follow.", minidumpContents, in put.readLine()); 191 "The minidump contents should follow.", MINIDUMP_CONTENTS, i nput.readLine());
104 assertNull("There should be nothing else in the file", input.readLin e()); 192 assertNull("There should be nothing else in the file", input.readLin e());
105 } catch (IOException e) {
106 fail(e.toString());
107 } finally { 193 } finally {
108 StreamUtil.closeQuietly(input); 194 StreamUtil.closeQuietly(input);
109 } 195 }
110 } 196 }
197
198 @MediumTest
199 public void testSimpleExtraction_SansJobScheduler() throws IOException {
200 setJobSchedulerEnabled(false);
201 final File minidump = createMinidump("test.dmp");
202 Context testContext = new TestContext(getInstrumentation().getTargetCont ext());
203
204 LogcatExtractionRunnable runnable = new TestLogcatExtractionRunnable(tes tContext, minidump);
205 runnable.run();
206
207 verifyMinidumpWithLogcat("test.dmp.try0");
208 }
209
210 @MediumTest
211 public void testSimpleExtraction_WithJobScheduler() throws IOException {
212 // The JobScheduler API is only available as of Android L.
213 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
214
215 setJobSchedulerEnabled(true);
216 final File minidump = createMinidump("test.dmp");
217 Context testContext = new TestContext(getInstrumentation().getTargetCont ext());
218
219 LogcatExtractionRunnable runnable = new TestLogcatExtractionRunnable(tes tContext, minidump);
220 runnable.run();
221
222 verifyMinidumpWithLogcat("test.dmp.try0");
223 }
111 } 224 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698