SystemJobServiceTest.java revision 681a8d809fe41189c9d590d33b986b98170e4963
1/* 2 * Copyright 2018 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 17package androidx.work.impl.background.systemjob; 18 19import static android.support.test.espresso.matcher.ViewMatchers.assertThat; 20 21import static org.hamcrest.CoreMatchers.is; 22import static org.mockito.Mockito.mock; 23import static org.mockito.Mockito.when; 24 25import android.app.job.JobParameters; 26import android.arch.core.executor.ArchTaskExecutor; 27import android.arch.core.executor.TaskExecutor; 28import android.net.Uri; 29import android.os.PersistableBundle; 30import android.support.annotation.NonNull; 31import android.support.test.InstrumentationRegistry; 32import android.support.test.filters.SdkSuppress; 33import android.support.test.filters.SmallTest; 34import android.support.test.runner.AndroidJUnit4; 35 36import androidx.work.BaseWork; 37import androidx.work.State; 38import androidx.work.Work; 39import androidx.work.WorkManagerTest; 40import androidx.work.Worker; 41import androidx.work.impl.WorkDatabase; 42import androidx.work.impl.WorkManagerImpl; 43import androidx.work.impl.model.WorkSpecDao; 44import androidx.work.impl.utils.taskexecutor.InstantTaskExecutorRule; 45import androidx.work.worker.InfiniteTestWorker; 46 47import org.junit.After; 48import org.junit.Before; 49import org.junit.Rule; 50import org.junit.Test; 51import org.junit.runner.RunWith; 52 53@RunWith(AndroidJUnit4.class) 54@SdkSuppress(minSdkVersion = WorkManagerImpl.MIN_JOB_SCHEDULER_API_LEVEL) 55public class SystemJobServiceTest extends WorkManagerTest { 56 57 @Rule 58 public InstantTaskExecutorRule mRule = new InstantTaskExecutorRule(); 59 60 private WorkDatabase mDatabase; 61 private SystemJobService mSystemJobService; 62 63 @Before 64 public void setUp() { 65 ArchTaskExecutor.getInstance().setDelegate(new TaskExecutor() { 66 @Override 67 public void executeOnDiskIO(@NonNull Runnable runnable) { 68 runnable.run(); 69 } 70 71 @Override 72 public void postToMainThread(@NonNull Runnable runnable) { 73 runnable.run(); 74 } 75 76 @Override 77 public boolean isMainThread() { 78 return true; 79 } 80 }); 81 82 mDatabase = WorkManagerImpl.getInstance(InstrumentationRegistry.getTargetContext()) 83 .getWorkDatabase(); 84 mSystemJobService = new SystemJobService(); // Bleh. 85 mSystemJobService.onCreate(); 86 } 87 88 @After 89 public void tearDown() { 90 mSystemJobService.onDestroy(); 91 ArchTaskExecutor.getInstance().setDelegate(null); 92 } 93 94 @Test 95 @SmallTest 96 public void testOnStopJob_ResetsWorkStatus() throws InterruptedException { 97 Work work = new Work.Builder(InfiniteTestWorker.class).build(); 98 insertWork(work); 99 100 JobParameters mockParams = createMockJobParameters(work.getId()); 101 mSystemJobService.onStartJob(mockParams); 102 103 // TODO(sumir): Remove later. Put here because WorkerWrapper sets state to RUNNING. 104 Thread.sleep(1000L); 105 106 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 107 assertThat(workSpecDao.getState(work.getId()), is(State.RUNNING)); 108 109 mSystemJobService.onStopJob(mockParams); 110 assertThat(workSpecDao.getState(work.getId()), is(State.ENQUEUED)); 111 } 112 113 @Test 114 @SmallTest 115 public void testOnStopJob_ReschedulesWhenNotCancelled() { 116 Work work = new Work.Builder(InfiniteTestWorker.class).build(); 117 insertWork(work); 118 119 JobParameters mockParams = createMockJobParameters(work.getId()); 120 assertThat(mSystemJobService.onStartJob(mockParams), is(true)); 121 assertThat(mSystemJobService.onStopJob(mockParams), is(true)); 122 } 123 124 @Test 125 @SmallTest 126 public void testOnStopJob_DoesNotRescheduleWhenCancelled() { 127 Work work = new Work.Builder(InfiniteTestWorker.class).build(); 128 insertWork(work); 129 130 JobParameters mockParams = createMockJobParameters(work.getId()); 131 assertThat(mSystemJobService.onStartJob(mockParams), is(true)); 132 WorkManagerImpl.getInstance(InstrumentationRegistry.getTargetContext()) 133 .cancelWorkById(work.getId()); 134 assertThat(mSystemJobService.onStopJob(mockParams), is(false)); 135 } 136 137 @Test 138 @SmallTest 139 public void testStartJob_ReturnsFalseWithDuplicateJob() { 140 Work work = new Work.Builder(InfiniteTestWorker.class).build(); 141 insertWork(work); 142 143 JobParameters mockParams = createMockJobParameters(work.getId()); 144 assertThat(mSystemJobService.onStartJob(mockParams), is(true)); 145 assertThat(mSystemJobService.onStartJob(mockParams), is(false)); 146 } 147 148 @Test 149 @SmallTest 150 @SdkSuppress(minSdkVersion = 24) 151 public void testStartJob_PassesContentUriTriggers() throws InterruptedException { 152 Work work = new Work.Builder(ContentUriTriggerLoggingWorker.class).build(); 153 insertWork(work); 154 155 final String[] testContentAuthorities = new String[] { 156 work.getId(), 157 "yet another " + work.getId() 158 }; 159 160 final Uri[] testContentUris = new Uri[] { 161 Uri.parse("http://www.android.com"), 162 Uri.parse("http://www.google.com") 163 }; 164 165 JobParameters mockParams = createMockJobParameters(work.getId()); 166 when(mockParams.getTriggeredContentAuthorities()).thenReturn(testContentAuthorities); 167 when(mockParams.getTriggeredContentUris()).thenReturn(testContentUris); 168 169 assertThat(ContentUriTriggerLoggingWorker.sTimesUpdated, is(0)); 170 assertThat(mSystemJobService.onStartJob(mockParams), is(true)); 171 172 Thread.sleep(1000L); 173 174 assertThat(ContentUriTriggerLoggingWorker.sTimesUpdated, is(1)); 175 assertThat(ContentUriTriggerLoggingWorker.sTriggeredContentAuthorities, 176 is(testContentAuthorities)); 177 assertThat(ContentUriTriggerLoggingWorker.sTriggeredContentUris, is(testContentUris)); 178 } 179 180 private JobParameters createMockJobParameters(String id) { 181 JobParameters jobParameters = mock(JobParameters.class); 182 183 PersistableBundle persistableBundle = new PersistableBundle(); 184 persistableBundle.putString(SystemJobInfoConverter.EXTRA_WORK_SPEC_ID, id); 185 when(jobParameters.getExtras()).thenReturn(persistableBundle); 186 187 return jobParameters; 188 } 189 190 private void insertWork(BaseWork work) { 191 mDatabase.workSpecDao().insertWorkSpec(getWorkSpec(work)); 192 } 193 194 public static class ContentUriTriggerLoggingWorker extends Worker { 195 196 static int sTimesUpdated = 0; 197 static String[] sTriggeredContentAuthorities; 198 static Uri[] sTriggeredContentUris; 199 200 @Override 201 public WorkerResult doWork() { 202 synchronized (ContentUriTriggerLoggingWorker.class) { 203 ++sTimesUpdated; 204 sTriggeredContentAuthorities = getTriggeredContentAuthorities(); 205 sTriggeredContentUris = getTriggeredContentUris(); 206 } 207 return WorkerResult.SUCCESS; 208 } 209 } 210} 211