1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.documentsui.services; 18 19 import static com.android.documentsui.services.FileOperationService.OPERATION_COPY; 20 import static com.android.documentsui.services.FileOperations.createBaseIntent; 21 import static com.android.documentsui.services.FileOperations.createJobId; 22 import static com.google.android.collect.Lists.newArrayList; 23 24 import android.content.Context; 25 import android.content.Intent; 26 import android.net.Uri; 27 import android.test.ServiceTestCase; 28 import android.test.suitebuilder.annotation.MediumTest; 29 30 import com.android.documentsui.model.DocumentInfo; 31 import com.android.documentsui.model.DocumentStack; 32 import com.android.documentsui.services.Job.Listener; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 37 /** 38 * TODO: Test progress updates. 39 */ 40 @MediumTest 41 public class FileOperationServiceTest extends ServiceTestCase<FileOperationService> { 42 43 private static final DocumentInfo ALPHA_DOC = createDoc("alpha"); 44 private static final DocumentInfo BETA_DOC = createDoc("alpha"); 45 private static final DocumentInfo GAMMA_DOC = createDoc("gamma"); 46 private static final DocumentInfo DELTA_DOC = createDoc("delta"); 47 48 private FileOperationService mService; 49 private TestScheduledExecutorService mExecutor; 50 private TestJobFactory mJobFactory; 51 52 public FileOperationServiceTest() { 53 super(FileOperationService.class); 54 } 55 56 @Override 57 protected void setUp() throws Exception { 58 super.setUp(); 59 setupService(); // must be called first for our test setup to work correctly. 60 61 mExecutor = new TestScheduledExecutorService(); 62 mJobFactory = new TestJobFactory(); 63 64 // Install test doubles. 65 mService = getService(); 66 67 assertNull(mService.executor); 68 mService.executor = mExecutor; 69 70 assertNull(mService.jobFactory); 71 mService.jobFactory = mJobFactory; 72 } 73 74 public void testRunsJobs() throws Exception { 75 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 76 startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC)); 77 78 mExecutor.runAll(); 79 mJobFactory.assertAllJobsStarted(); 80 } 81 82 public void testRunsJobs_AfterExceptionInJobCreation() throws Exception { 83 startService(createCopyIntent(new ArrayList<DocumentInfo>(), BETA_DOC)); 84 startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC)); 85 86 mJobFactory.assertJobsCreated(1); 87 88 mExecutor.runAll(); 89 mJobFactory.assertAllJobsStarted(); 90 } 91 92 public void testRunsJobs_AfterFailure() throws Exception { 93 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 94 startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC)); 95 96 mJobFactory.jobs.get(0).fail(ALPHA_DOC); 97 98 mExecutor.runAll(); 99 mJobFactory.assertAllJobsStarted(); 100 } 101 102 public void testHoldsWakeLockWhileWorking() throws Exception { 103 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 104 105 assertTrue(mService.holdsWakeLock()); 106 } 107 108 public void testReleasesWakeLock_AfterSuccess() throws Exception { 109 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 110 111 assertTrue(mService.holdsWakeLock()); 112 mExecutor.runAll(); 113 assertFalse(mService.holdsWakeLock()); 114 } 115 116 public void testReleasesWakeLock_AfterFailure() throws Exception { 117 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 118 119 assertTrue(mService.holdsWakeLock()); 120 mExecutor.runAll(); 121 assertFalse(mService.holdsWakeLock()); 122 } 123 124 public void testShutdownStopsExecutor_AfterSuccess() throws Exception { 125 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 126 127 mExecutor.assertAlive(); 128 129 mExecutor.runAll(); 130 shutdownService(); 131 132 mExecutor.assertShutdown(); 133 } 134 135 public void testShutdownStopsExecutor_AfterMixedFailures() throws Exception { 136 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 137 startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC)); 138 139 mJobFactory.jobs.get(0).fail(ALPHA_DOC); 140 141 mExecutor.runAll(); 142 shutdownService(); 143 144 mExecutor.assertShutdown(); 145 } 146 147 public void testShutdownStopsExecutor_AfterTotalFailure() throws Exception { 148 startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC)); 149 startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC)); 150 151 mJobFactory.jobs.get(0).fail(ALPHA_DOC); 152 mJobFactory.jobs.get(1).fail(GAMMA_DOC); 153 154 mExecutor.runAll(); 155 shutdownService(); 156 157 mExecutor.assertShutdown(); 158 } 159 160 private Intent createCopyIntent(ArrayList<DocumentInfo> files, DocumentInfo dest) 161 throws Exception { 162 DocumentStack stack = new DocumentStack(); 163 stack.push(dest); 164 165 return createBaseIntent(OPERATION_COPY, getContext(), createJobId(), files, stack); 166 } 167 168 private static DocumentInfo createDoc(String name) { 169 // Doesn't need to be valid content Uri, just some urly looking thing. 170 Uri uri = new Uri.Builder() 171 .scheme("content") 172 .authority("com.android.documentsui.testing") 173 .path(name) 174 .build(); 175 176 return createDoc(uri); 177 } 178 179 private static DocumentInfo createDoc(Uri destination) { 180 DocumentInfo destDoc = new DocumentInfo(); 181 destDoc.derivedUri = destination; 182 return destDoc; 183 } 184 185 private final class TestJobFactory extends Job.Factory { 186 187 final List<TestJob> jobs = new ArrayList<>(); 188 189 void assertAllJobsStarted() { 190 for (TestJob job : jobs) { 191 job.assertStarted(); 192 } 193 } 194 195 void assertJobsCreated(int expected) { 196 assertEquals(expected, jobs.size()); 197 } 198 199 @Override 200 Job createCopy(Context service, Context appContext, Listener listener, String id, 201 DocumentStack stack, List<DocumentInfo> srcs) { 202 203 if (srcs.isEmpty()) { 204 throw new RuntimeException("Empty srcs not supported!"); 205 } 206 207 TestJob job = new TestJob(service, appContext, listener, OPERATION_COPY, id, stack); 208 jobs.add(job); 209 return job; 210 } 211 } 212 } 213