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; 18 19import static androidx.work.State.BLOCKED; 20import static androidx.work.State.FAILED; 21import static androidx.work.State.SUCCEEDED; 22import static androidx.work.impl.Scheduler.MAX_SCHEDULER_LIMIT; 23 24import static org.hamcrest.CoreMatchers.equalTo; 25import static org.hamcrest.CoreMatchers.is; 26import static org.hamcrest.CoreMatchers.notNullValue; 27import static org.hamcrest.MatcherAssert.assertThat; 28import static org.hamcrest.Matchers.containsInAnyOrder; 29 30import android.support.test.filters.SmallTest; 31import android.support.test.runner.AndroidJUnit4; 32 33import androidx.work.impl.model.WorkSpec; 34import androidx.work.impl.model.WorkSpecDao; 35import androidx.work.worker.TestWorker; 36 37import org.junit.Test; 38import org.junit.runner.RunWith; 39 40import java.util.List; 41import java.util.concurrent.TimeUnit; 42 43@RunWith(AndroidJUnit4.class) 44public class WorkSpecDaoTest extends DatabaseTest { 45 46 @Test 47 @SmallTest 48 public void testEligibleWorkSpecsForScheduling() { 49 long startTime = System.currentTimeMillis(); 50 OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class) 51 .setPeriodStartTime( 52 startTime + TimeUnit.HOURS.toMillis(1), 53 TimeUnit.MILLISECONDS) 54 .build(); 55 OneTimeWorkRequest succeeded = new OneTimeWorkRequest.Builder(TestWorker.class) 56 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 57 .setInitialState(SUCCEEDED) 58 .build(); 59 OneTimeWorkRequest scheduled = new OneTimeWorkRequest.Builder(TestWorker.class) 60 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 61 .build(); 62 OneTimeWorkRequest enqueued = new OneTimeWorkRequest.Builder(TestWorker.class) 63 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 64 .build(); 65 66 insertWork(work); 67 insertWork(succeeded); 68 insertWork(scheduled); 69 insertWork(enqueued); 70 71 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 72 // Treat the scheduled request as previously scheduled 73 workSpecDao.markWorkSpecScheduled(scheduled.getStringId(), System.currentTimeMillis()); 74 List<WorkSpec> eligibleWorkSpecs = 75 workSpecDao.getEligibleWorkForScheduling(MAX_SCHEDULER_LIMIT); 76 77 assertThat(eligibleWorkSpecs.size(), equalTo(2)); 78 assertThat(eligibleWorkSpecs, 79 containsInAnyOrder(work.getWorkSpec(), enqueued.getWorkSpec())); 80 } 81 82 @Test 83 @SmallTest 84 public void testScheduledWorkSpecCount() { 85 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 86 87 long startTime = System.currentTimeMillis(); 88 OneTimeWorkRequest enqueued = new OneTimeWorkRequest.Builder(TestWorker.class) 89 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 90 .build(); 91 OneTimeWorkRequest succeeded = new OneTimeWorkRequest.Builder(TestWorker.class) 92 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 93 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 94 .setInitialState(SUCCEEDED) 95 .build(); 96 OneTimeWorkRequest failed = new OneTimeWorkRequest.Builder(TestWorker.class) 97 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 98 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 99 .setInitialState(FAILED) 100 .build(); 101 102 insertWork(enqueued); 103 insertWork(succeeded); 104 insertWork(failed); 105 106 List<WorkSpec> eligibleWorkSpecs = 107 workSpecDao.getEligibleWorkForScheduling(MAX_SCHEDULER_LIMIT); 108 assertThat(eligibleWorkSpecs, notNullValue()); 109 assertThat(eligibleWorkSpecs.size(), is(1)); 110 assertThat(eligibleWorkSpecs, containsInAnyOrder(enqueued.getWorkSpec())); 111 } 112 113 @Test 114 @SmallTest 115 public void testAlreadyScheduledWorkIsNotRescheduled() { 116 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 117 118 long startTime = System.currentTimeMillis(); 119 OneTimeWorkRequest enqueued = new OneTimeWorkRequest.Builder(TestWorker.class) 120 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) // already scheduled 121 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 122 .build(); 123 OneTimeWorkRequest succeeded = new OneTimeWorkRequest.Builder(TestWorker.class) 124 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 125 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 126 .setInitialState(SUCCEEDED) 127 .build(); 128 OneTimeWorkRequest failed = new OneTimeWorkRequest.Builder(TestWorker.class) 129 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 130 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 131 .setInitialState(FAILED) 132 .build(); 133 134 insertWork(enqueued); 135 insertWork(succeeded); 136 insertWork(failed); 137 138 List<WorkSpec> eligibleWorkSpecs = 139 workSpecDao.getEligibleWorkForScheduling(MAX_SCHEDULER_LIMIT); 140 assertThat(eligibleWorkSpecs, notNullValue()); 141 assertThat(eligibleWorkSpecs.size(), is(0)); 142 } 143 144 @Test 145 @SmallTest 146 public void testResetScheduledState() { 147 WorkSpecDao workSpecDao = mDatabase.workSpecDao(); 148 149 long startTime = System.currentTimeMillis(); 150 OneTimeWorkRequest enqueued = new OneTimeWorkRequest.Builder(TestWorker.class) 151 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 152 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 153 .build(); 154 OneTimeWorkRequest succeeded = new OneTimeWorkRequest.Builder(TestWorker.class) 155 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 156 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 157 .setInitialState(SUCCEEDED) 158 .build(); 159 OneTimeWorkRequest blocked = new OneTimeWorkRequest.Builder(TestWorker.class) 160 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 161 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 162 .setInitialState(BLOCKED) 163 .build(); 164 OneTimeWorkRequest failed = new OneTimeWorkRequest.Builder(TestWorker.class) 165 .setScheduleRequestedAt(startTime, TimeUnit.MILLISECONDS) 166 .setPeriodStartTime(startTime, TimeUnit.MILLISECONDS) 167 .setInitialState(FAILED) 168 .build(); 169 170 insertWork(enqueued); 171 workSpecDao.markWorkSpecScheduled(enqueued.getStringId(), startTime); 172 173 insertWork(succeeded); 174 insertWork(failed); 175 insertWork(blocked); 176 177 workSpecDao.resetScheduledState(); 178 179 List<WorkSpec> eligibleWorkSpecs = 180 workSpecDao.getEligibleWorkForScheduling(MAX_SCHEDULER_LIMIT); 181 assertThat(eligibleWorkSpecs.size(), is(1)); 182 // Not using contains in any order as the scheduleRequestedAt changes post reset. 183 assertThat(eligibleWorkSpecs.get(0).id, is(enqueued.getStringId())); 184 } 185} 186