@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); uploadIntent.putExtra(MinidumpUploadService.FINISHED_LOGCAT_EXTRACTION_KEY, true); 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)); }