OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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.android_webview.test.crash; | 5 package org.chromium.android_webview.test.crash; |
6 | 6 |
7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; | 7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; |
8 | 8 |
9 import android.content.Context; | 9 import android.content.Context; |
10 import android.os.ParcelFileDescriptor; | 10 import android.os.ParcelFileDescriptor; |
(...skipping 13 matching lines...) Expand all Loading... | |
24 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionMa nager; | 24 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionMa nager; |
25 import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory; | 25 import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory; |
26 | 26 |
27 import java.io.File; | 27 import java.io.File; |
28 import java.io.FileInputStream; | 28 import java.io.FileInputStream; |
29 import java.io.FileNotFoundException; | 29 import java.io.FileNotFoundException; |
30 import java.io.IOException; | 30 import java.io.IOException; |
31 import java.io.InterruptedIOException; | 31 import java.io.InterruptedIOException; |
32 import java.io.OutputStream; | 32 import java.io.OutputStream; |
33 import java.net.HttpURLConnection; | 33 import java.net.HttpURLConnection; |
34 import java.net.MalformedURLException; | |
35 import java.net.URL; | |
34 import java.util.ArrayList; | 36 import java.util.ArrayList; |
35 import java.util.List; | 37 import java.util.List; |
36 import java.util.concurrent.CountDownLatch; | 38 import java.util.concurrent.CountDownLatch; |
37 import java.util.concurrent.TimeUnit; | 39 import java.util.concurrent.TimeUnit; |
38 | 40 |
39 /** | 41 /** |
40 * Instrumentation tests for MinidumpUploader. | 42 * Instrumentation tests for MinidumpUploader. |
41 */ | 43 */ |
42 public class MinidumpUploaderTest extends CrashTestCase { | 44 public class MinidumpUploaderTest extends CrashTestCase { |
43 private static final String TAG = "MinidumpUploaderTest"; | 45 private static final String TAG = "MinidumpUploaderTest"; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 // This file should have been left untouched. | 141 // This file should have been left untouched. |
140 assertTrue(maxTriesFile.exists()); | 142 assertTrue(maxTriesFile.exists()); |
141 } | 143 } |
142 | 144 |
143 /** | 145 /** |
144 * Utility method for running {@param minidumpUploader}.uploadAllMinidumps o n the UI thread to | 146 * Utility method for running {@param minidumpUploader}.uploadAllMinidumps o n the UI thread to |
145 * avoid breaking any assertions about running on the UI thread. | 147 * avoid breaking any assertions about running on the UI thread. |
146 */ | 148 */ |
147 private static void uploadAllMinidumpsOnUiThread(final MinidumpUploader mini dumpUploader, | 149 private static void uploadAllMinidumpsOnUiThread(final MinidumpUploader mini dumpUploader, |
148 final MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallba ck) { | 150 final MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallba ck) { |
151 uploadAllMinidumpsOnUiThread( | |
152 minidumpUploader, uploadsFinishedCallback, false /* blockUntilJo bPosted */); | |
153 } | |
154 | |
155 private static void uploadAllMinidumpsOnUiThread(final MinidumpUploader mini dumpUploader, | |
156 final MinidumpUploader.UploadsFinishedCallback uploadsFinishedCallba ck, | |
157 boolean blockUntilJobPosted) { | |
158 final CountDownLatch jobPostedLatch = new CountDownLatch(1); | |
149 ThreadUtils.runOnUiThread(new Runnable() { | 159 ThreadUtils.runOnUiThread(new Runnable() { |
150 @Override | 160 @Override |
151 public void run() { | 161 public void run() { |
152 minidumpUploader.uploadAllMinidumps(uploadsFinishedCallback); | 162 minidumpUploader.uploadAllMinidumps(uploadsFinishedCallback); |
163 jobPostedLatch.countDown(); | |
153 } | 164 } |
154 }); | 165 }); |
166 if (blockUntilJobPosted) { | |
167 try { | |
168 jobPostedLatch.await(); | |
169 } catch (InterruptedException e) { | |
170 throw new RuntimeException(e); | |
Ilya Sherman
2017/02/11 01:00:47
What's the reason to catch the exception just to r
gsennton
2017/02/13 10:46:55
Just to avoid having to declare the Exception type
| |
171 } | |
172 } | |
155 } | 173 } |
156 | 174 |
157 private static void uploadMinidumpsSync( | 175 private static void uploadMinidumpsSync( |
158 MinidumpUploader minidumpUploader, final boolean expectReschedule) { | 176 MinidumpUploader minidumpUploader, final boolean expectReschedule) { |
159 final CountDownLatch uploadsFinishedLatch = new CountDownLatch(1); | 177 final CountDownLatch uploadsFinishedLatch = new CountDownLatch(1); |
160 uploadAllMinidumpsOnUiThread( | 178 uploadAllMinidumpsOnUiThread( |
161 minidumpUploader, new MinidumpUploader.UploadsFinishedCallback() { | 179 minidumpUploader, new MinidumpUploader.UploadsFinishedCallback() { |
162 @Override | 180 @Override |
163 public void uploadsFinished(boolean reschedule) { | 181 public void uploadsFinished(boolean reschedule) { |
164 assertEquals(expectReschedule, reschedule); | 182 assertEquals(expectReschedule, reschedule); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 expectedSecondFile = new File(mCrashDir, secondFile.getName().replac e(".dmp", ".up")); | 287 expectedSecondFile = new File(mCrashDir, secondFile.getName().replac e(".dmp", ".up")); |
270 } else { | 288 } else { |
271 File uploadedFirstFile = | 289 File uploadedFirstFile = |
272 new File(mCrashDir, firstFile.getName().replace(".dmp", ".up ")); | 290 new File(mCrashDir, firstFile.getName().replace(".dmp", ".up ")); |
273 assertTrue(uploadedFirstFile.exists()); | 291 assertTrue(uploadedFirstFile.exists()); |
274 expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".tr y1"); | 292 expectedSecondFile = new File(mCrashDir, secondFile.getName() + ".tr y1"); |
275 } | 293 } |
276 assertTrue(expectedSecondFile.exists()); | 294 assertTrue(expectedSecondFile.exists()); |
277 } | 295 } |
278 | 296 |
279 private static class StallingOutputStream extends OutputStream { | 297 private static class StallingHttpUrlConnectionFactory implements HttpURLConn ectionFactory { |
280 @Override | 298 private final CountDownLatch mStopStallingLatch; |
281 public void write(int b) throws IOException { | 299 private final boolean mSucceed; |
300 | |
301 private class StallingOutputStream extends OutputStream { | |
302 @Override | |
303 public void write(int b) throws IOException { | |
304 try { | |
305 mStopStallingLatch.await(); | |
306 } catch (InterruptedException e) { | |
307 throw new InterruptedIOException(e.toString()); | |
308 } | |
309 if (!mSucceed) { | |
310 throw new IOException(); | |
311 } | |
312 } | |
313 } | |
314 | |
315 public StallingHttpUrlConnectionFactory(CountDownLatch stopStallingLatch , boolean succeed) { | |
316 mStopStallingLatch = stopStallingLatch; | |
317 mSucceed = succeed; | |
318 } | |
319 | |
320 public HttpURLConnection createHttpURLConnection(String url) { | |
282 try { | 321 try { |
283 TimeUnit.MINUTES.sleep(100); | 322 return new MinidumpUploadCallableTest.TestHttpURLConnection(new URL(url)) { |
284 } catch (InterruptedException e) { | 323 @Override |
285 throw new InterruptedIOException(e.toString()); | 324 public OutputStream getOutputStream() { |
325 return new StallingOutputStream(); | |
326 } | |
327 }; | |
328 } catch (MalformedURLException e) { | |
329 return null; | |
286 } | 330 } |
287 } | 331 } |
288 } | 332 } |
289 | 333 |
290 private static class StallingHttpUrlConnectionFactory implements HttpURLConn ectionFactory { | |
291 public HttpURLConnection createHttpURLConnection(String url) { | |
292 return new HttpURLConnection(null) { | |
293 @Override | |
294 public OutputStream getOutputStream() throws IOException { | |
295 return new StallingOutputStream(); | |
296 } | |
297 | |
298 @Override | |
299 public void connect() {} | |
300 | |
301 @Override | |
302 public void disconnect() {} | |
303 | |
304 @Override | |
305 public boolean usingProxy() { | |
306 return false; | |
307 } | |
308 }; | |
309 } | |
310 } | |
311 | |
312 private static class FailingHttpUrlConnectionFactory implements HttpURLConne ctionFactory { | 334 private static class FailingHttpUrlConnectionFactory implements HttpURLConne ctionFactory { |
313 public HttpURLConnection createHttpURLConnection(String url) { | 335 public HttpURLConnection createHttpURLConnection(String url) { |
314 return null; | 336 return null; |
315 } | 337 } |
316 } | 338 } |
317 | 339 |
318 /** | 340 /** |
319 * Test that ensure we can interrupt the MinidumpUploader when uploading min idumps. | 341 * Test that ensures we can interrupt the MinidumpUploader when uploading mi nidumps. |
320 */ | 342 */ |
321 @MediumTest | 343 @MediumTest |
322 public void testCancelMinidumpUploads() throws IOException { | 344 public void testCancelMinidumpUploadsFailedUpload() throws IOException { |
345 testCancellation(false /* successfulUpload */); | |
346 } | |
347 | |
348 /** | |
349 * Test that ensures interrupting our upload-job will not interrupt the firs t upload. | |
350 */ | |
351 @MediumTest | |
352 public void testCancelingWontCancelFirstUpload() throws IOException { | |
353 testCancellation(true /* successfulUpload */); | |
354 } | |
355 | |
356 private void testCancellation(final boolean successfulUpload) throws IOExcep tion { | |
323 final CrashReportingPermissionManager permManager = | 357 final CrashReportingPermissionManager permManager = |
324 new MockCrashReportingPermissionManager() { | 358 new MockCrashReportingPermissionManager() { |
325 { mIsEnabledForTests = true; } | 359 { mIsEnabledForTests = true; } |
326 }; | 360 }; |
327 MinidumpUploader minidumpUploader = new MinidumpUploaderImpl( | 361 final CountDownLatch stopStallingLatch = new CountDownLatch(1); |
362 MinidumpUploaderImpl minidumpUploader = new MinidumpUploaderImpl( | |
328 getInstrumentation().getTargetContext(), false /* cleanOutMinidu mps */) { | 363 getInstrumentation().getTargetContext(), false /* cleanOutMinidu mps */) { |
329 @Override | 364 @Override |
330 public MinidumpUploadCallable createMinidumpUploadCallable( | 365 public MinidumpUploadCallable createMinidumpUploadCallable( |
331 File minidumpFile, File logfile) { | 366 File minidumpFile, File logfile) { |
332 return new MinidumpUploadCallable( | 367 return new MinidumpUploadCallable(minidumpFile, logfile, |
333 minidumpFile, logfile, new StallingHttpUrlConnectionFact ory(), permManager); | 368 new StallingHttpUrlConnectionFactory(stopStallingLatch, successfulUpload), |
369 permManager); | |
334 } | 370 } |
335 @Override | 371 @Override |
336 public PlatformServiceBridge createPlatformServiceBridge() { | 372 public PlatformServiceBridge createPlatformServiceBridge() { |
337 return new TestPlatformServiceBridge( | 373 return new TestPlatformServiceBridge( |
338 true /* canUseGms*/, permManager.isUsageAndCrashReportin gPermittedByUser()); | 374 true /* canUseGms*/, permManager.isUsageAndCrashReportin gPermittedByUser()); |
339 } | 375 } |
340 }; | 376 }; |
341 | 377 |
342 File firstFile = createMinidumpFileInCrashDir("123_abc.dmp0"); | 378 File firstFile = createMinidumpFileInCrashDir("123_abc.dmp0"); |
343 File nonExpectedFirstUploadFile = new File(mCrashDir, firstFile.getName( ) + ".up"); | 379 File expectedFirstUploadFile = |
344 File nonExpectedFirstRetryFile = new File(mCrashDir, firstFile.getName() + ".try1"); | 380 new File(mCrashDir, firstFile.getName().replace(".dmp", ".up")); |
381 File expectedFirstRetryFile = new File(mCrashDir, firstFile.getName() + ".try1"); | |
345 | 382 |
346 // This is run on the UI thread to avoid failing any assertOnUiThread as sertions. | 383 // This is run on the UI thread to avoid failing any assertOnUiThread as sertions. |
347 uploadAllMinidumpsOnUiThread( | 384 uploadAllMinidumpsOnUiThread(minidumpUploader, |
348 minidumpUploader, new MinidumpUploader.UploadsFinishedCallback() { | 385 new MinidumpUploader.UploadsFinishedCallback() { |
349 @Override | 386 @Override |
350 public void uploadsFinished(boolean reschedule) { | 387 public void uploadsFinished(boolean reschedule) { |
351 fail("This method shouldn't be called when we interrupt uploads."); | 388 if (successfulUpload) { |
389 assertFalse(reschedule); | |
390 } else { | |
391 fail("This method shouldn't be called when a cancele d upload fails."); | |
392 } | |
352 } | 393 } |
353 }); | 394 }, |
395 // Block until job posted - otherwise the worker thread might no t have been created | |
396 // before we try to join it. | |
397 true /* blockUntilJobPosted */); | |
354 minidumpUploader.cancelUploads(); | 398 minidumpUploader.cancelUploads(); |
399 stopStallingLatch.countDown(); | |
400 // Wait until our job finished. | |
401 try { | |
402 minidumpUploader.joinWorkerThreadForTesting(); | |
403 } catch (InterruptedException e) { | |
404 throw new RuntimeException(e); | |
405 } | |
355 | 406 |
356 assertTrue(firstFile.exists()); | 407 if (successfulUpload) { |
357 assertFalse(nonExpectedFirstUploadFile.exists()); | 408 // When the upload succeeds we expect the file to be renamed. |
358 assertFalse(nonExpectedFirstRetryFile.exists()); | 409 assertFalse(firstFile.exists()); |
410 assertTrue(expectedFirstUploadFile.exists()); | |
411 assertFalse(expectedFirstRetryFile.exists()); | |
412 } else { | |
413 // When the upload fails we won't change the minidump at all. | |
414 assertTrue(firstFile.exists()); | |
415 assertFalse(expectedFirstUploadFile.exists()); | |
416 assertFalse(expectedFirstRetryFile.exists()); | |
417 } | |
359 } | 418 } |
360 | 419 |
361 /** | 420 /** |
362 * Ensures that the minidump copying works together with the minidump upload ing. | 421 * Ensures that the minidump copying works together with the minidump upload ing. |
363 */ | 422 */ |
364 @MediumTest | 423 @MediumTest |
365 public void testCopyAndUploadWebViewMinidump() throws FileNotFoundException, IOException { | 424 public void testCopyAndUploadWebViewMinidump() throws FileNotFoundException, IOException { |
366 final CrashFileManager fileManager = new CrashFileManager( | 425 final CrashFileManager fileManager = new CrashFileManager( |
367 CrashReceiverService.getWebViewCrashDir(getInstrumentation().get TargetContext())); | 426 CrashReceiverService.getWebViewCrashDir(getInstrumentation().get TargetContext())); |
368 // Note that these minidump files are set up directly in the cache dir - not in the WebView | 427 // Note that these minidump files are set up directly in the cache dir - not in the WebView |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 assertEquals(numMinidumps, uploadedFiles.length); | 671 assertEquals(numMinidumps, uploadedFiles.length); |
613 return uploadedFiles; | 672 return uploadedFiles; |
614 } | 673 } |
615 | 674 |
616 private File createMinidumpFileInCrashDir(String name) throws IOException { | 675 private File createMinidumpFileInCrashDir(String name) throws IOException { |
617 File minidumpFile = new File(mCrashDir, name); | 676 File minidumpFile = new File(mCrashDir, name); |
618 setUpMinidumpFile(minidumpFile, BOUNDARY); | 677 setUpMinidumpFile(minidumpFile, BOUNDARY); |
619 return minidumpFile; | 678 return minidumpFile; |
620 } | 679 } |
621 } | 680 } |
OLD | NEW |